diff --git a/.gitignore b/.gitignore index 2889d12b5f..723e94d4bc 100644 --- a/.gitignore +++ b/.gitignore @@ -83,8 +83,9 @@ venv/ #Ignore temporary installed phpunit /bin/phpunit -#Ignore cache file +#Ignore cache files .php_cs.cache +.php-cs-fixer.cache #ignore avatar picture cache path /avatar diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php new file mode 100644 index 0000000000..9345ee617e --- /dev/null +++ b/.php-cs-fixer.dist.php @@ -0,0 +1,93 @@ +. + */ + +declare(strict_types=1); + +$finder = PhpCsFixer\Finder::create() + ->in(__DIR__) + ->notPath('addon') + ->notPath('bin/dev') + ->notPath('config') + ->notPath('doc') + ->notPath('images') + ->notPath('mods') + ->notPath('spec') + ->notPath('vendor') + ->notPath('view/asset') + ->notPath('lang') + ->notPath('view/smarty3/compiled'); + +$config = new PhpCsFixer\Config(); +return $config + ->setRules([ + '@PSR1' => true, + '@PSR2' => true, + '@PSR12' => true, + 'align_multiline_comment' => true, + 'array_indentation' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'binary_operator_spaces' => [ + 'default' => 'single_space', + 'operators' => [ + '=>' => 'align_single_space_minimal', + '=' => 'align_single_space_minimal', + '??' => 'align_single_space_minimal', + ], + ], + 'blank_line_after_namespace' => true, + 'braces' => [ + 'position_after_anonymous_constructs' => 'same', + 'position_after_control_structures' => 'same', + 'position_after_functions_and_oop_constructs' => 'next', + ], + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'function_declaration' => [ + 'closure_function_spacing' => 'one', + ], + 'indentation_type' => true, + 'line_ending' => true, + 'list_syntax' => [ + 'syntax' => 'long', + ], + 'lowercase_keywords' => true, + 'method_argument_space' => [], + 'no_closing_tag' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unused_imports' => true, + 'single_blank_line_at_eof' => true, + 'single_class_element_per_statement' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'switch_case_space' => true, + 'ternary_operator_spaces' => false, + 'visibility_required' => [ + 'elements' => ['property', 'method'] + ], + 'new_with_braces' => true, + ]) + ->setFinder($finder) + ->setIndent("\t"); diff --git a/.php_cs.dist b/.php_cs.dist index 897c6f1104..1d7056bdc1 100644 --- a/.php_cs.dist +++ b/.php_cs.dist @@ -6,6 +6,7 @@ require_once __DIR__ . '/bin/dev/php-cs-fixer/vendor/autoload.php'; $finder = PhpCsFixer\Finder::create() ->in(__DIR__) + ->notPath('addon') ->notPath('bin/dev') ->notPath('config') ->notPath('doc') diff --git a/composer.json b/composer.json index 21603c7b27..47946cd4e6 100644 --- a/composer.json +++ b/composer.json @@ -29,12 +29,12 @@ "ext-xml": "*", "asika/simple-console": "^1.0", "bacon/bacon-qr-code": "^2.0.0", - "divineomega/password_exposed": "^2.8", + "divineomega/password_exposed": "^3", "enyo/dropzone": "^5.9", "ezyang/htmlpurifier": "^4.7", "friendica/json-ld": "^1.0", "geekwright/po": "^2.0", - "guzzlehttp/guzzle": "^6.5", + "guzzlehttp/guzzle": "^7", "guzzlehttp/oauth-subscriber": "^0.6", "kornrunner/blurhash": "^1.2", "league/html-to-markdown": "^4.8", @@ -135,7 +135,8 @@ "mockery/mockery": "^1.3", "mikey179/vfsstream": "^1.6", "phpunit/phpunit": "^9", - "dms/phpunit-arraysubset-asserts": "^0.3.1" + "dms/phpunit-arraysubset-asserts": "^0.3.1", + "friendsofphp/php-cs-fixer": "^3.46" }, "scripts": { "test": "phpunit", @@ -149,6 +150,8 @@ "cs:fix": [ "@cs:install", "bin/dev/php-cs-fixer/vendor/bin/php-cs-fixer fix" - ] + ], + "cs:check-v3": "vendor/bin/php-cs-fixer check --diff", + "cs:fix-v3": "vendor/bin/php-cs-fixer fix" } } diff --git a/composer.lock b/composer.lock index a541913811..f5a039f8b1 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": "082b16e2c88895f1a03d5b0ffe678ba7", + "content-hash": "7f060ee5d2e04fbbb363890277eca8fd", "packages": [ { "name": "asika/simple-console", @@ -507,38 +507,101 @@ }, { "name": "divineomega/password_exposed", - "version": "v2.8.0", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/DivineOmega/password_exposed.git", - "reference": "908ed8e62ef95411bd0f866e29c69cef2bbca880" + "reference": "327f93ee5cab54622077bcae721412b55be16720" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DivineOmega/password_exposed/zipball/908ed8e62ef95411bd0f866e29c69cef2bbca880", - "reference": "908ed8e62ef95411bd0f866e29c69cef2bbca880", + "url": "https://api.github.com/repos/DivineOmega/password_exposed/zipball/327f93ee5cab54622077bcae721412b55be16720", + "reference": "327f93ee5cab54622077bcae721412b55be16720", "shasum": "" }, "require": { "divineomega/do-file-cache-psr-6": "^2.0", - "guzzlehttp/guzzle": "^6.3", - "paragonie/certainty": "^1|^2", - "php": ">=5.6" + "divineomega/psr-18-guzzle-adapter": "^1.0", + "nyholm/psr7": "^1.0", + "paragonie/certainty": "^2.4", + "php": "^7.1||^8.0", + "php-http/discovery": "^1.6", + "psr/cache": "^1.0", + "psr/http-client": "^1.0", + "psr/http-factory-implementation": "^1.0", + "psr/http-message": "^1.0", + "psr/http-message-implementation": "^1.0" }, "require-dev": { "fzaninotto/faker": "^1.7", + "kriswallsmith/buzz": "^1.0", "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^6.5", - "vimeo/psalm": "^1" + "phpunit/phpunit": "^7.0||^8.0", + "symfony/cache": "^4.2.12", + "vimeo/psalm": "^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "files": [ + "src/PasswordExposedFunction.php" + ], + "psr-4": { + "DivineOmega\\PasswordExposed\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-only" + ], + "authors": [ + { + "name": "Jordan Hall", + "email": "jordan@hall05.co.uk" + }, + { + "name": "Contributors", + "homepage": "https://github.com/DivineOmega/password_exposed/graphs/contributors" + } + ], + "description": "This PHP package provides a `password_exposed` helper function, that uses the haveibeenpwned.com API to check if a password has been exposed in a data breach.", + "homepage": "https://github.com/DivineOmega/password_exposed", + "funding": [ + { + "url": "https://github.com/DivineOmega", + "type": "github" + } + ], + "time": "2021-04-20T09:34:23+00:00" + }, + { + "name": "divineomega/psr-18-guzzle-adapter", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/DivineOmega/psr-18-guzzle-adapter.git", + "reference": "a2bdcddd4d4a17aac460e58d1e064e6bd2de5e57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DivineOmega/psr-18-guzzle-adapter/zipball/a2bdcddd4d4a17aac460e58d1e064e6bd2de5e57", + "reference": "a2bdcddd4d4a17aac460e58d1e064e6bd2de5e57", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^6.3||^7.0", + "php": "^7.1||^8.0", + "psr/http-client": "^1.0" }, "type": "library", "autoload": { "psr-4": { - "DivineOmega\\PasswordExposed\\": "src/" - }, - "files": [ - "src/PasswordExposedFunction.php" - ] + "DivineOmega\\Psr18GuzzleAdapter\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -550,8 +613,14 @@ "email": "jordan@hall05.co.uk" } ], - "description": "This PHP package provides a `password_exposed` helper function, that uses the haveibeenpwned.com API to check if a password has been exposed in a data breach.", - "time": "2019-01-25T12:00:28+00:00" + "description": "PSR-18 adapter for the Guzzle HTTP client", + "funding": [ + { + "url": "https://github.com/DivineOmega", + "type": "github" + } + ], + "time": "2021-04-20T08:50:57+00:00" }, { "name": "enyo/dropzone", @@ -871,37 +940,47 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.8", + "version": "7.8.1", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981" + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a52f0440530b54fa079ce76e8c5d196a42cad981", - "reference": "a52f0440530b54fa079ce76e8c5d196a42cad981", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", + "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.0", - "guzzlehttp/psr7": "^1.9", - "php": ">=5.5", - "symfony/polyfill-intl-idn": "^1.17" + "guzzlehttp/promises": "^1.5.3 || ^2.0.1", + "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", - "psr/log": "^1.1" + "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, "type": "library", "extra": { - "branch-alias": { - "dev-master": "6.5-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { @@ -954,13 +1033,14 @@ } ], "description": "Guzzle is a PHP HTTP client library", - "homepage": "http://guzzlephp.org/", "keywords": [ "client", "curl", "framework", "http", "http client", + "psr-18", + "psr-7", "rest", "web service" ], @@ -978,7 +1058,7 @@ "type": "tidelift" } ], - "time": "2022-06-20T22:16:07+00:00" + "time": "2023-12-03T20:35:24+00:00" }, { "name": "guzzlehttp/oauth-subscriber", @@ -1037,29 +1117,33 @@ }, { "name": "guzzlehttp/promises", - "version": "1.5.3", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e" + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/67ab6e18aaa14d753cc148911d273f6e6cb6721e", - "reference": "67ab6e18aaa14d753cc148911d273f6e6cb6721e", + "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", + "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Promise\\": "src/" } @@ -1108,42 +1192,48 @@ "type": "tidelift" } ], - "time": "2023-05-21T12:31:43+00:00" + "time": "2023-12-03T20:19:20+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.9.1", + "version": "2.6.2", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b" + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/e4490cabc77465aaee90b20cfc9a770f8c04be6b", - "reference": "e4490cabc77465aaee90b20cfc9a770f8c04be6b", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", + "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", "shasum": "" }, "require": { - "php": ">=5.4.0", - "psr/http-message": "~1.0", - "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0" }, "provide": { + "psr/http-factory-implementation": "1.0", "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" + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.36 || ^9.6.15" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", + "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + } + }, "autoload": { - "files": [ - "src/functions_include.php" - ], "psr-4": { "GuzzleHttp\\Psr7\\": "src/" } @@ -1182,6 +1272,11 @@ "name": "Tobias Schultze", "email": "webmaster@tubo-world.de", "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" } ], "description": "PSR-7 message implementation that also provides common utility methods", @@ -1209,7 +1304,7 @@ "type": "tidelift" } ], - "time": "2023-04-17T16:00:37+00:00" + "time": "2023-12-03T20:05:35+00:00" }, { "name": "kornrunner/blurhash", @@ -2316,11 +2411,11 @@ }, { "name": "npm-asset/moment", - "version": "2.29.4", + "version": "2.30.1", "dist": { "type": "tar", - "url": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "shasum": "3dbe052889fe7c1b2ed966fcb3a77328964ef108" + "url": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "shasum": "f8c91c07b7a786e30c59926df530b4eac96974ae" }, "type": "npm-asset-library", "extra": { @@ -2394,7 +2489,7 @@ "time", "validate" ], - "time": "2022-07-06T16:01:32+00:00" + "time": "2023-12-27T10:38:43+00:00" }, { "name": "npm-asset/perfect-scrollbar", @@ -2680,6 +2775,80 @@ ], "time": "2018-01-24T10:49:39+00:00" }, + { + "name": "nyholm/psr7", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/aa5fc277a4f5508013d571341ade0c3886d4d00e", + "reference": "aa5fc277a4f5508013d571341ade0c3886d4d00e", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-11-13T09:31:12+00:00" + }, { "name": "paragonie/certainty", "version": "v2.8.2", @@ -3083,17 +3252,91 @@ "time": "2018-01-25T20:47:17+00:00" }, { - "name": "phpseclib/phpseclib", - "version": "3.0.34", + "name": "php-http/discovery", + "version": "1.19.2", "source": { "type": "git", - "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "56c79f16a6ae17e42089c06a2144467acc35348a" + "url": "https://github.com/php-http/discovery.git", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/56c79f16a6ae17e42089c06a2144467acc35348a", - "reference": "56c79f16a6ae17e42089c06a2144467acc35348a", + "url": "https://api.github.com/repos/php-http/discovery/zipball/61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "reference": "61e1a1eb69c92741f5896d9e05fb8e9d7e8bb0cb", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "symfony/phpunit-bridge": "^6.2" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "time": "2023-11-30T16:49:05+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "3.0.35", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/4b1827beabce71953ca479485c0ae9c51287f2fe", + "reference": "4b1827beabce71953ca479485c0ae9c51287f2fe", "shasum": "" }, "require": { @@ -3186,7 +3429,7 @@ "type": "tidelift" } ], - "time": "2023-11-27T11:13:31+00:00" + "time": "2023-12-29T01:59:53+00:00" }, { "name": "pragmarx/google2fa", @@ -3922,128 +4165,35 @@ "time": "2020-11-03T09:10:25+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.28.0", + "name": "symfony/deprecation-contracts", + "version": "v2.5.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/ecaafce9f77234a6a449d29e49267ba10499116d", - "reference": "ecaafce9f77234a6a449d29e49267ba10499116d", - "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": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "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" - ], - "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-01-26T09:30:37+00:00" - }, - { - "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", "shasum": "" }, "require": { "php": ">=7.1" }, - "suggest": { - "ext-intl": "For best performance" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.28-dev" + "dev-main": "2.5-dev" }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, - "classmap": [ - "Resources/stubs" + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -4060,16 +4210,8 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for intl's Normalizer class and related functions", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "intl", - "normalizer", - "polyfill", - "portable", - "shim" - ], "funding": [ { "url": "https://symfony.com/sponsor", @@ -4084,7 +4226,7 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/polyfill-php56", @@ -4151,79 +4293,6 @@ ], "time": "2020-10-23T14:02:19+00:00" }, - { - "name": "symfony/polyfill-php72", - "version": "v1.28.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, - "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" - ], - "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-01-26T09:26:14+00:00" - }, { "name": "ua-parser/uap-php", "version": "v3.9.14", @@ -4691,6 +4760,210 @@ } ], "packages-dev": [ + { + "name": "composer/pcre", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.3", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-10-11T07:11:09+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.0", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2023-08-31T09:50:34+00:00" + }, + { + "name": "composer/xdebug-handler", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/composer/xdebug-handler.git", + "reference": "ced299686f41dce890debac69273b47ffe98a40c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "shasum": "" + }, + "require": { + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", + "psr/log": "^1 || ^2 || ^3" + }, + "require-dev": { + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Composer\\XdebugHandler\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "John Stevenson", + "email": "john-stevenson@blueyonder.co.uk" + } + ], + "description": "Restarts a process without Xdebug.", + "keywords": [ + "Xdebug", + "performance" + ], + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-02-25T21:32:43+00:00" + }, { "name": "dms/phpunit-arraysubset-asserts", "version": "v0.3.1", @@ -4798,6 +5071,93 @@ ], "time": "2022-12-30T00:15:36+00:00" }, + { + "name": "friendsofphp/php-cs-fixer", + "version": "v3.46.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "be6831c9af1740470d2a773119b9273f8ac1c3d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/be6831c9af1740470d2a773119b9273f8ac1c3d2", + "reference": "be6831c9af1740470d2a773119b9273f8ac1c3d2", + "shasum": "" + }, + "require": { + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0", + "sebastian/diff": "^4.0 || ^5.0", + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" + }, + "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", + "justinrainbow/json-schema": "^5.2", + "keradus/cli-executor": "^2.1", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.7", + "php-cs-fixer/accessible-object": "^1.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpunit/phpunit": "^9.6 || ^10.5.5", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + }, + "suggest": { + "ext-dom": "For handling output formats in XML", + "ext-mbstring": "For handling non-UTF8 characters." + }, + "bin": [ + "php-cs-fixer" + ], + "type": "application", + "autoload": { + "psr-4": { + "PhpCsFixer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Dariusz Rumiński", + "email": "dariusz.ruminski@gmail.com" + } + ], + "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], + "funding": [ + { + "url": "https://github.com/keradus", + "type": "github" + } + ], + "time": "2024-01-03T21:38:46+00:00" + }, { "name": "hamcrest/hamcrest-php", "version": "v2.0.1", @@ -5024,25 +5384,27 @@ }, { "name": "nikic/php-parser", - "version": "v4.18.0", + "version": "v5.0.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc", + "reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -5050,7 +5412,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -5072,7 +5434,7 @@ "parser", "php" ], - "time": "2023-12-10T21:03:43+00:00" + "time": "2024-01-07T17:17:35+00:00" }, { "name": "phar-io/manifest", @@ -5179,23 +5541,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ca2bd87d2f9215904682a9cb9bb37dda98e76089", + "reference": "ca2bd87d2f9215904682a9cb9bb37dda98e76089", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -5248,7 +5610,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2023-12-22T06:47:57+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5573,6 +5935,52 @@ ], "time": "2023-12-01T16:55:19+00:00" }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "time": "2019-01-08T18:20:26+00:00" + }, { "name": "sebastian/cli-parser", "version": "1.0.1", @@ -5800,20 +6208,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -5849,7 +6257,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/diff", @@ -6107,20 +6515,20 @@ }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -6156,7 +6564,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -6473,6 +6881,1256 @@ ], "time": "2020-09-28T06:39:44+00:00" }, + { + "name": "symfony/console", + "version": "v5.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "4b4d8cd118484aa604ec519062113dd87abde18c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/4b4d8cd118484aa604ec519062113dd87abde18c", + "reference": "4b4d8cd118484aa604ec519062113dd87abde18c", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" + }, + "conflict": { + "psr/log": ">=3", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, + "require-dev": { + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "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-12-08T13:33:03+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v5.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "e3bca343efeb613f843c254e7718ef17c9bdf7a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/e3bca343efeb613f843c254e7718ef17c9bdf7a3", + "reference": "e3bca343efeb613f843c254e7718ef17c9bdf7a3", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/event-dispatcher-contracts": "^2|^3", + "symfony/polyfill-php80": "^1.16" + }, + "conflict": { + "symfony/dependency-injection": "<4.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/expression-language": "^4.4|^5.0|^6.0", + "symfony/http-foundation": "^4.4|^5.0|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^4.4|^5.0|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "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": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "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-12-27T21:12:56+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v2.5.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "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": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "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": "2022-01-02T09:53:40+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v5.4.25", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0ce3a62c9579a53358d3a7eb6b3dfb79789a6364", + "reference": "0ce3a62c9579a53358d3a7eb6b3dfb79789a6364", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "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": "Provides basic utilities for the filesystem", + "homepage": "https://symfony.com", + "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-05-31T13:04:02+00:00" + }, + { + "name": "symfony/finder", + "version": "v5.4.27", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/ff4bce3c33451e7ec778070e45bd23f74214cd5d", + "reference": "ff4bce3c33451e7ec778070e45bd23f74214cd5d", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php80": "^1.16" + }, + "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", + "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-07-31T08:02:31+00:00" + }, + { + "name": "symfony/options-resolver", + "version": "v5.4.21", + "source": { + "type": "git", + "url": "https://github.com/symfony/options-resolver.git", + "reference": "4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9", + "reference": "4fe5cf6ede71096839f0e4b4444d65dd3a7c1eb9", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-php73": "~1.0", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\OptionsResolver\\": "" + }, + "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": "Provides an improved replacement for the array_replace PHP function", + "homepage": "https://symfony.com", + "keywords": [ + "config", + "configuration", + "options" + ], + "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-02-14T08:03:56+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "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-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "875e90aeea2777b6f135677f618529449334a612" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "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 grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "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-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "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" + ], + "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-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "42292d99c55abe617799667f454222c54c60e229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "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" + ], + "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-07-28T09:04:16+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "reference": "fe2f306d1d9d346a7fee353d0d5012e401e984b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "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 backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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-01-26T09:26:14+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.28.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.28-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "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 backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "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-01-26T09:26:14+00:00" + }, + { + "name": "symfony/process", + "version": "v5.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/8fa22178dfc368911dbd513b431cd9b06f9afe7a", + "reference": "8fa22178dfc368911dbd513b431cd9b06f9afe7a", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "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": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "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-12-02T08:41:43+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v1.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/191afdcb5804db960d26d8566b7e9a2843cab3a0", + "reference": "191afdcb5804db960d26d8566b7e9a2843cab3a0", + "shasum": "" + }, + "require": { + "php": "^7.1.3" + }, + "suggest": { + "psr/container": "", + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "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": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "time": "2019-05-28T07:50:59+00:00" + }, + { + "name": "symfony/stopwatch", + "version": "v5.4.21", + "source": { + "type": "git", + "url": "https://github.com/symfony/stopwatch.git", + "reference": "f83692cd869a6f2391691d40a01e8acb89e76fee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f83692cd869a6f2391691d40a01e8acb89e76fee", + "reference": "f83692cd869a6f2391691d40a01e8acb89e76fee", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/service-contracts": "^1|^2|^3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Stopwatch\\": "" + }, + "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": "Provides a way to profile code", + "homepage": "https://symfony.com", + "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-02-14T08:03:56+00:00" + }, + { + "name": "symfony/string", + "version": "v5.4.34", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "e3f98bfc7885c957488f443df82d97814a3ce061" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/e3f98bfc7885c957488f443df82d97814a3ce061", + "reference": "e3f98bfc7885c957488f443df82d97814a3ce061", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "~1.15" + }, + "conflict": { + "symfony/translation-contracts": ">=3.0" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0|^6.0", + "symfony/http-client": "^4.4|^5.0|^6.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "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": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "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-12-09T13:20:28+00:00" + }, { "name": "theseer/tokenizer", "version": "1.2.2", diff --git a/mod/photos.php b/mod/photos.php index a4434f4936..322ddd1599 100644 --- a/mod/photos.php +++ b/mod/photos.php @@ -215,14 +215,14 @@ function photos_post(App $a) // get the list of photos we are about to delete if ($visitor) { $r = DBA::toArray(DBA::p( - "SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `contact-id` = ? AND `uid` = ? AND `album` = ?", + "SELECT distinct(`resource-id`) AS `rid` FROM `photo` WHERE `contact-id` = ? AND `uid` = ? AND `album` = ?", $visitor, $page_owner_uid, $album )); } else { $r = DBA::toArray(DBA::p( - "SELECT distinct(`resource-id`) as `rid` FROM `photo` WHERE `uid` = ? AND `album` = ?", + "SELECT distinct(`resource-id`) AS `rid` FROM `photo` WHERE `uid` = ? AND `album` = ?", DI::userSession()->getLocalUserId(), $album )); @@ -762,7 +762,7 @@ function photos_content(App $a) $total = 0; $r = DBA::toArray(DBA::p( - "SELECT `resource-id`, max(`scale`) AS `scale` FROM `photo` WHERE `uid` = ? AND `album` = ? + "SELECT `resource-id`, MAX(`scale`) AS `scale` FROM `photo` WHERE `uid` = ? AND `album` = ? AND `scale` <= 4 $sql_extra GROUP BY `resource-id`", $owner_uid, $album @@ -782,9 +782,9 @@ function photos_content(App $a) } $r = DBA::toArray(DBA::p( - "SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, - ANY_VALUE(`type`) AS `type`, max(`scale`) AS `scale`, ANY_VALUE(`desc`) as `desc`, - ANY_VALUE(`created`) as `created` + "SELECT `resource-id`, MIN(`id`) AS `id`, MIN(`filename`) AS `filename`, + MIN(`type`) AS `type`, MAX(`scale`) AS `scale`, MIN(`desc`) AS `desc`, + MIN(`created`) AS `created` FROM `photo` WHERE `uid` = ? AND `album` = ? AND `scale` <= 4 $sql_extra GROUP BY `resource-id` ORDER BY `created` $order LIMIT ? , ?", intval($owner_uid), @@ -1167,11 +1167,11 @@ function photos_content(App $a) } if (!empty($conv_responses['like'][$link_item['uri']])) { - $like = DI::conversation()->formatActivity($conv_responses['like'][$link_item['uri']]['links'], 'like', $link_item['id']); + $like = DI::conversation()->formatActivity($conv_responses['like'][$link_item['uri']]['links'], 'like', $link_item['id'], '', []); } if (!empty($conv_responses['dislike'][$link_item['uri']])) { - $dislike = DI::conversation()->formatActivity($conv_responses['dislike'][$link_item['uri']]['links'], 'dislike', $link_item['id']); + $dislike = DI::conversation()->formatActivity($conv_responses['dislike'][$link_item['uri']]['links'], 'dislike', $link_item['id'], '', []); } if (($can_post || Security::canWriteToUserWall($owner_uid))) { diff --git a/src/Console/User.php b/src/Console/User.php index 0c2f17eb3c..e175c54477 100644 --- a/src/Console/User.php +++ b/src/Console/User.php @@ -58,7 +58,7 @@ class User extends \Asika\SimpleConsole\Console console user - Modify user settings per console commands. Usage bin/console user password [] [-h|--help|-?] [-v] - bin/console user add [ [ [ []]]] [-h|--help|-?] [-v] + bin/console user add [ [ [ [ []]]]] [-h|--help|-?] [-v] bin/console user delete [] [-y] [-h|--help|-?] [-v] bin/console user allow [] [-h|--help|-?] [-v] bin/console user deny [] [-h|--help|-?] [-v] @@ -228,10 +228,11 @@ HELP; */ private function addUser() { - $name = $this->getArgument(1); - $nick = $this->getArgument(2); - $email = $this->getArgument(3); - $lang = $this->getArgument(4); + $name = $this->getArgument(1); + $nick = $this->getArgument(2); + $email = $this->getArgument(3); + $lang = $this->getArgument(4); + $avatar = $this->getArgument(5); if (empty($name)) { $this->out($this->l10n->t('Enter user name: ')); @@ -262,10 +263,15 @@ HELP; $lang = CliPrompt::prompt(); } + if (empty($avatar)) { + $this->out($this->l10n->t('Enter URL of an image to use as avatar (optional): ')); + $avatar = CliPrompt::prompt(); + } + if (empty($lang)) { return UserModel::createMinimal($name, $email, $nick); } else { - return UserModel::createMinimal($name, $email, $nick, $lang); + return UserModel::createMinimal($name, $email, $nick, $lang, $avatar); } } diff --git a/src/Contact/Avatar.php b/src/Contact/Avatar.php index 28d277a1a2..371e645232 100644 --- a/src/Contact/Avatar.php +++ b/src/Contact/Avatar.php @@ -80,7 +80,7 @@ class Avatar return $fields; } - $img_str = $fetchResult->getBody(); + $img_str = $fetchResult->getBodyString(); if (empty($img_str)) { Logger::debug('Avatar is invalid', ['avatar' => $avatar]); return $fields; diff --git a/src/Content/Item.php b/src/Content/Item.php index 9c5c3e7480..c7438d2593 100644 --- a/src/Content/Item.php +++ b/src/Content/Item.php @@ -383,7 +383,7 @@ class Item 'url' => $item['author-link'], 'alias' => $item['author-alias'], ]; - $profile_link = Contact::magicLinkByContact($author, $item['author-link']); + $profile_link = Contact::magicLinkByContact($author, Contact::getProfileLink($author)); if (strpos($profile_link, 'contact/redir/') === 0) { $status_link = $profile_link . '?' . http_build_query(['url' => $item['author-link'] . '/status']); $photos_link = $profile_link . '?' . http_build_query(['url' => $item['author-link'] . '/photos']); diff --git a/src/Content/OEmbed.php b/src/Content/OEmbed.php index 8a4634539a..674728036b 100644 --- a/src/Content/OEmbed.php +++ b/src/Content/OEmbed.php @@ -120,7 +120,7 @@ class OEmbed ['https://www.youtube.com/', 'https://player.vimeo.com/'], $href); $result = DI::httpClient()->fetchFull($href . '&maxwidth=' . $a->getThemeInfoValue('videowidth')); if ($result->getReturnCode() === 200) { - $json_string = $result->getBody(); + $json_string = $result->getBodyString(); break; } } diff --git a/src/Content/Widget/Hovercard.php b/src/Content/Widget/Hovercard.php index 91107b0fc3..d229f764e8 100644 --- a/src/Content/Widget/Hovercard.php +++ b/src/Content/Widget/Hovercard.php @@ -45,19 +45,21 @@ class Hovercard $actions = []; } + $contact_url = Contact::getProfileLink($contact); + // Move the contact data to the profile array so we can deliver it to $tpl = Renderer::getMarkupTemplate('hovercard.tpl'); return Renderer::replaceMacros($tpl, [ '$profile' => [ 'name' => $contact['name'], 'nick' => $contact['nick'], - 'addr' => $contact['addr'] ?: $contact['url'], + 'addr' => $contact['addr'] ?: $contact_url, 'thumb' => Contact::getThumb($contact), 'url' => Contact::magicLinkByContact($contact), 'nurl' => $contact['nurl'], 'location' => $contact['location'], 'about' => $contact['about'], - 'network_link' => Strings::formatNetworkName($contact['network'], $contact['url']), + 'network_link' => Strings::formatNetworkName($contact['network'], $contact_url), 'tags' => $contact['keywords'], 'bd' => $contact['bd'] <= DBA::NULL_DATE ? '' : $contact['bd'], 'account_type' => Contact::getAccountType($contact['contact-type']), diff --git a/src/Content/Widget/VCard.php b/src/Content/Widget/VCard.php index 9963629f17..13c90f5712 100644 --- a/src/Content/Widget/VCard.php +++ b/src/Content/Widget/VCard.php @@ -50,11 +50,7 @@ class VCard Logger::warning('Incomplete contact', ['contact' => $contact ?? []]); } - if (!Network::isValidHttpUrl($contact['url']) && Network::isValidHttpUrl($contact['alias'])) { - $contact_url = $contact['alias']; - } else { - $contact_url = $contact['url']; - } + $contact_url = Contact::getProfileLink($contact); if ($contact['network'] != '') { $network_link = Strings::formatNetworkName($contact['network'], $contact_url); diff --git a/src/Core/Logger/Handler/ErrorHandler.php b/src/Core/Logger/Handler/ErrorHandler.php index f08344b4ee..ab959bbb17 100644 --- a/src/Core/Logger/Handler/ErrorHandler.php +++ b/src/Core/Logger/Handler/ErrorHandler.php @@ -263,7 +263,7 @@ class ErrorHandler public function handleError(int $code, string $message, string $file = '', int $line = 0, ?array $context = []): bool { if ($this->handleOnlyReportedErrors && !(error_reporting() & $code)) { - return false; + return true; } // fatal error codes are ignored if a fatal error handler is present as well to avoid duplicate log entries diff --git a/src/Core/Search.php b/src/Core/Search.php index d59febc8a8..c0e39fcea2 100644 --- a/src/Core/Search.php +++ b/src/Core/Search.php @@ -234,7 +234,7 @@ class Search $p = $page > 1 ? 'p=' . $page : ''; $curlResult = DI::httpClient()->get(self::getGlobalDirectory() . '/search/people?' . $p . '&q=' . urlencode($search), HttpClientAccept::JSON); if ($curlResult->isSuccess()) { - $searchResult = json_decode($curlResult->getBody(), true); + $searchResult = json_decode($curlResult->getBodyString(), true); if (!empty($searchResult['profiles'])) { // Converting Directory Search results into contact-looking records $return = array_map(function ($result) { diff --git a/src/Core/Storage/Type/ExternalResource.php b/src/Core/Storage/Type/ExternalResource.php index 6e04edde17..ee1e90f82b 100644 --- a/src/Core/Storage/Type/ExternalResource.php +++ b/src/Core/Storage/Type/ExternalResource.php @@ -70,12 +70,12 @@ class ExternalResource implements ICanReadFromStorage } if (!empty($fetchResult) && $fetchResult->isSuccess()) { $this->logger->debug('Got picture', ['Content-Type' => $fetchResult->getHeader('Content-Type'), 'uid' => $data->uid, 'url' => $data->url]); - return $fetchResult->getBody(); + return $fetchResult->getBodyString(); } else { if (empty($fetchResult)) { throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference)); } else { - throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBody())); + throw new ReferenceStorageException(sprintf('External resource failed to get %s', $reference), $fetchResult->getReturnCode(), new Exception($fetchResult->getBodyString())); } } } diff --git a/src/Core/System.php b/src/Core/System.php index 0479053530..df8cb9377e 100644 --- a/src/Core/System.php +++ b/src/Core/System.php @@ -230,7 +230,7 @@ class System * @param int $offset How many calls to shave off the top of the stack, for example if * this is called from a centralized method that isn't relevant to the callstack * @param bool $full If enabled, the callstack is not compacted - * @param array $exclude + * @param array $exclude * @return string */ public static function callstack(int $depth = 4, int $offset = 0, bool $full = false, array $exclude = []): string diff --git a/src/Database/DBA.php b/src/Database/DBA.php index d3ccca101f..d5e5a7e59b 100644 --- a/src/Database/DBA.php +++ b/src/Database/DBA.php @@ -132,22 +132,6 @@ class DBA return DI::dba()->connected(); } - /** - * Replaces ANY_VALUE() function by MIN() function, - * if the database server does not support ANY_VALUE(). - * - * Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5). - * ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html - * A standard fall-back is to use MIN(). - * - * @param string $sql An SQL string without the values - * @return string The input SQL string modified if necessary. - */ - public static function anyValueFallback(string $sql): string - { - return DI::dba()->anyValueFallback($sql); - } - /** * beautifies the query - useful for "SHOW PROCESSLIST" * diff --git a/src/Database/Database.php b/src/Database/Database.php index d7b9a17e9b..c296683d2b 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -439,28 +439,6 @@ class Database return $connected; } - /** - * Replaces ANY_VALUE() function by MIN() function, - * if the database server does not support ANY_VALUE(). - * - * Considerations for Standard SQL, or MySQL with ONLY_FULL_GROUP_BY (default since 5.7.5). - * ANY_VALUE() is available from MySQL 5.7.5 https://dev.mysql.com/doc/refman/5.7/en/miscellaneous-functions.html - * A standard fall-back is to use MIN(). - * - * @param string $sql An SQL string without the values - * - * @return string The input SQL string modified if necessary. - */ - public function anyValueFallback(string $sql): string - { - $server_info = $this->serverInfo(); - if (version_compare($server_info, '5.7.5', '<') || - (stripos($server_info, 'MariaDB') !== false)) { - $sql = str_ireplace('ANY_VALUE(', 'MIN(', $sql); - } - return $sql; - } - /** * Replaces the ? placeholders with the parameters in the $args array * @@ -532,7 +510,6 @@ class Database } $sql = DBA::cleanQuery($sql); - $sql = $this->anyValueFallback($sql); $orig_sql = $sql; @@ -1440,7 +1417,7 @@ class Database private function escapeFields(array $fields, array $options): array { // In the case of a "GROUP BY" we have to add all the ORDER fields to the fieldlist. - // This needs to done to apply the "ANY_VALUE(...)" treatment from below to them. + // This needs to done to apply the "MIN(...)" treatment from below to them. // Otherwise MySQL would report errors. if (!empty($options['group_by']) && !empty($options['order'])) { foreach ($options['order'] as $key => $field) { @@ -1461,7 +1438,7 @@ class Database $value = DBA::quoteIdentifier($field); if (!empty($options['group_by']) && !in_array($field, $options['group_by'])) { - $value = 'ANY_VALUE(' . $value . ') AS ' . $value; + $value = 'MIN(' . $value . ') AS ' . $value; } }); diff --git a/src/Model/APContact.php b/src/Model/APContact.php index 6f1f7d3834..032dd37f39 100644 --- a/src/Model/APContact.php +++ b/src/Model/APContact.php @@ -198,11 +198,11 @@ class APContact try { $curlResult = HTTPSignature::fetchRaw($url); - $failed = empty($curlResult) || empty($curlResult->getBody()) || + $failed = empty($curlResult) || empty($curlResult->getBodyString()) || (!$curlResult->isSuccess() && ($curlResult->getReturnCode() != 410)); if (!$failed) { - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); $failed = empty($data) || !is_array($data); } diff --git a/src/Model/Contact.php b/src/Model/Contact.php index 31bc0ad01a..a08035389b 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -2305,7 +2305,7 @@ class Contact try { $fetchResult = HTTPSignature::fetchRaw($avatar, 0, [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE]]); - $img_str = $fetchResult->getBody(); + $img_str = $fetchResult->getBodyString(); if (!empty($img_str)) { $image = new Image($img_str, Images::getMimeTypeByData($img_str)); if ($image->isValid()) { @@ -3495,6 +3495,21 @@ class Contact return array_column($contacts, 'id'); } + /** + * Return the link to the profile + * + * @param array $contact + * @return string + */ + public static function getProfileLink(array $contact): string + { + if (!empty($contact['alias']) && Network::isValidHttpUrl($contact['alias']) && (($contact['network'] ?? '') != Protocol::DFRN)) { + return $contact['alias']; + } else { + return $contact['url']; + } + } + /** * Returns a magic link to authenticate remote visitors * @@ -3553,7 +3568,7 @@ class Contact */ public static function magicLinkByContact(array $contact, string $url = ''): string { - $destination = $url ?: (!Network::isValidHttpUrl($contact['url']) && !empty($contact['alias']) && Network::isValidHttpUrl($contact['alias']) ? $contact['alias'] : $contact['url']); + $destination = $url ?: self::getProfileLink($contact); if (!DI::userSession()->isAuthenticated()) { return $destination; diff --git a/src/Model/GServer.php b/src/Model/GServer.php index e7f9530498..e40442384a 100644 --- a/src/Model/GServer.php +++ b/src/Model/GServer.php @@ -649,7 +649,7 @@ class GServer } if ($curlResult->isSuccess()) { - $json = json_decode($curlResult->getBody(), true); + $json = json_decode($curlResult->getBodyString(), true); if (!empty($json) && is_array($json)) { $data = self::fetchDataFromSystemActor($json, $serverdata); $serverdata = $data['server']; @@ -657,7 +657,7 @@ class GServer if (!$html_fetched && !in_array($serverdata['detection-method'], [self::DETECT_SYSTEM_ACTOR, self::DETECT_AP_COLLECTION])) { $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML); } - } elseif (!$html_fetched && (strlen($curlResult->getBody()) < 1000)) { + } elseif (!$html_fetched && (strlen($curlResult->getBodyString()) < 1000)) { $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML); } @@ -667,7 +667,7 @@ class GServer } } - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { + if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) { self::setFailureByUrl($url); return false; } @@ -677,7 +677,7 @@ class GServer $serverdata['network'] = Protocol::ACTIVITYPUB; $serverdata['platform'] = 'threads'; } - + if (($serverdata['network'] == Protocol::PHANTOM) || in_array($serverdata['detection-method'], self::DETECT_UNSPECIFIC)) { $serverdata = self::detectMastodonAlikes($url, $serverdata); } @@ -872,7 +872,7 @@ class GServer return; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (!is_array($data)) { return; } @@ -967,7 +967,7 @@ class GServer return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1059,7 +1059,7 @@ class GServer return []; } - $nodeinfo = json_decode($httpResult->getBody(), true); + $nodeinfo = json_decode($httpResult->getBodyString(), true); if (!is_array($nodeinfo) || empty($nodeinfo['links'])) { return []; @@ -1114,7 +1114,7 @@ class GServer return []; } - $nodeinfo = json_decode($curlResult->getBody(), true); + $nodeinfo = json_decode($curlResult->getBodyString(), true); if (!is_array($nodeinfo)) { return []; @@ -1214,7 +1214,7 @@ class GServer return []; } - $nodeinfo = json_decode($curlResult->getBody(), true); + $nodeinfo = json_decode($curlResult->getBodyString(), true); if (!is_array($nodeinfo)) { return []; } @@ -1331,7 +1331,7 @@ class GServer return []; } - $nodeinfo = json_decode($httpResult->getBody(), true); + $nodeinfo = json_decode($httpResult->getBodyString(), true); if (!is_array($nodeinfo)) { return []; @@ -1434,7 +1434,7 @@ class GServer return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1587,11 +1587,11 @@ class GServer { $name = 'nomad'; $curlResult = DI::httpClient()->get($url . '/manifest', 'application/manifest+json'); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return $name; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $name; } @@ -1608,11 +1608,11 @@ class GServer private static function getNomadVersion(string $url): string { $curlResult = DI::httpClient()->get($url . '/api/z/1.0/version', HttpClientAccept::JSON); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return ''; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return ''; } @@ -1634,7 +1634,7 @@ class GServer return false; } - $xrd = XML::parseString($curlResult->getBody(), true); + $xrd = XML::parseString($curlResult->getBodyString(), true); if (!is_object($xrd)) { return false; } @@ -1733,7 +1733,7 @@ class GServer return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1763,7 +1763,7 @@ class GServer return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1786,11 +1786,11 @@ class GServer private static function detectPeertube(string $url, array $serverdata): array { $curlResult = DI::httpClient()->get($url . '/api/v1/config', HttpClientAccept::JSON); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1834,11 +1834,11 @@ class GServer private static function detectNextcloud(string $url, array $serverdata, bool $validHostMeta): array { $curlResult = DI::httpClient()->get($url . '/status.php', HttpClientAccept::JSON); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1870,11 +1870,11 @@ class GServer private static function fetchWeeklyUsage(string $url, array $serverdata): array { $curlResult = DI::httpClient()->get($url . '/api/v1/instance/activity', HttpClientAccept::JSON); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1910,11 +1910,11 @@ class GServer private static function detectMastodonAlikes(string $url, array $serverdata): array { $curlResult = DI::httpClient()->get($url . '/api/v1/instance', HttpClientAccept::JSON); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data)) { return $serverdata; } @@ -1982,11 +1982,11 @@ class GServer private static function detectHubzilla(string $url, array $serverdata): array { $curlResult = DI::httpClient()->get($url . '/api/statusnet/config.json', HttpClientAccept::JSON); - if (!$curlResult->isSuccess() || ($curlResult->getBody() == '')) { + if (!$curlResult->isSuccess() || ($curlResult->getBodyString() == '')) { return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data) || empty($data['site'])) { return $serverdata; } @@ -2079,11 +2079,11 @@ class GServer { // Test for GNU Social $curlResult = DI::httpClient()->get($url . '/api/gnusocial/version.json', HttpClientAccept::JSON); - if ($curlResult->isSuccess() && ($curlResult->getBody() != '{"error":"not implemented"}') && - ($curlResult->getBody() != '') && (strlen($curlResult->getBody()) < 30)) { + if ($curlResult->isSuccess() && ($curlResult->getBodyString() != '{"error":"not implemented"}') && + ($curlResult->getBodyString() != '') && (strlen($curlResult->getBodyString()) < 30)) { $serverdata['platform'] = 'gnusocial'; // Remove junk that some GNU Social servers return - $serverdata['version'] = str_replace(chr(239) . chr(187) . chr(191), '', $curlResult->getBody()); + $serverdata['version'] = str_replace(chr(239) . chr(187) . chr(191), '', $curlResult->getBodyString()); $serverdata['version'] = str_replace(["\r", "\n", "\t"], '', $serverdata['version']); $serverdata['version'] = trim($serverdata['version'], '"'); $serverdata['network'] = Protocol::OSTATUS; @@ -2097,11 +2097,11 @@ class GServer // Test for Statusnet $curlResult = DI::httpClient()->get($url . '/api/statusnet/version.json', HttpClientAccept::JSON); - if ($curlResult->isSuccess() && ($curlResult->getBody() != '{"error":"not implemented"}') && - ($curlResult->getBody() != '') && (strlen($curlResult->getBody()) < 30)) { + if ($curlResult->isSuccess() && ($curlResult->getBodyString() != '{"error":"not implemented"}') && + ($curlResult->getBodyString() != '') && (strlen($curlResult->getBodyString()) < 30)) { // Remove junk that some GNU Social servers return - $serverdata['version'] = str_replace(chr(239).chr(187).chr(191), '', $curlResult->getBody()); + $serverdata['version'] = str_replace(chr(239).chr(187).chr(191), '', $curlResult->getBodyString()); $serverdata['version'] = str_replace(["\r", "\n", "\t"], '', $serverdata['version']); $serverdata['version'] = trim($serverdata['version'], '"'); @@ -2148,7 +2148,7 @@ class GServer return $serverdata; } - $data = json_decode($curlResult->getBody(), true); + $data = json_decode($curlResult->getBodyString(), true); if (empty($data) || empty($data['version'])) { return $serverdata; } @@ -2466,7 +2466,7 @@ class GServer $api = 'https://instances.social/api/1.0/instances/list?count=0'; $curlResult = DI::httpClient()->get($api, HttpClientAccept::JSON, [HttpClientOptions::HEADERS => ['Authorization' => ['Bearer ' . $accesstoken]]]); if ($curlResult->isSuccess()) { - $servers = json_decode($curlResult->getBody(), true); + $servers = json_decode($curlResult->getBodyString(), true); if (!empty($servers['instances'])) { foreach ($servers['instances'] as $server) { diff --git a/src/Model/Mail.php b/src/Model/Mail.php index 372ec8a452..08c703cecc 100644 --- a/src/Model/Mail.php +++ b/src/Model/Mail.php @@ -127,8 +127,6 @@ class Mail */ public static function send(int $sender_uid, int $recipient = 0, string $body = '', string $subject = '', string $replyto = ''): int { - $a = DI::app(); - if (!$recipient) { return -1; } @@ -246,77 +244,4 @@ class Mail return -3; } } - - /** - * @param array $recipient recipient, default empty - * @param string $body message body, default empty - * @param string $subject message subject, default empty - * @param string $replyto reply to, default empty - * @return int - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @throws \ImagickException - */ - public static function sendWall(array $recipient = [], string $body = '', string $subject = '', string $replyto = ''): int - { - if (!$recipient) { - return -1; - } - - if (!strlen($subject)) { - $subject = DI::l10n()->t('[no subject]'); - } - - $guid = System::createUUID(); - $uri = Item::newURI($guid); - - $me = Contact::getByURL($replyto); - if (!$me['name']) { - return -2; - } - - $conv_guid = System::createUUID(); - - $recip_handle = $recipient['nickname'] . '@' . substr(DI::baseUrl(), strpos(DI::baseUrl(), '://') + 3); - - $sender_handle = $me['addr']; - - $handles = $recip_handle . ';' . $sender_handle; - - $convid = null; - $fields = ['uid' => $recipient['uid'], 'guid' => $conv_guid, 'creator' => $sender_handle, - 'created' => DateTimeFormat::utcNow(), 'updated' => DateTimeFormat::utcNow(), - 'subject' => $subject, 'recips' => $handles]; - if (DBA::insert('conv', $fields)) { - $convid = DBA::lastInsertId(); - } - - if (!$convid) { - Logger::warning('conversation not found.'); - return -4; - } - - self::insert( - [ - 'uid' => $recipient['uid'], - 'guid' => $guid, - 'convid' => $convid, - 'from-name' => $me['name'], - 'from-photo' => $me['photo'], - 'from-url' => $me['url'], - 'contact-id' => 0, - 'title' => $subject, - 'body' => $body, - 'seen' => 0, - 'reply' => 0, - 'replied' => 0, - 'uri' => $uri, - 'parent-uri' => $me['url'], - 'created' => DateTimeFormat::utcNow(), - 'unknown' => 1 - ], - false - ); - - return 0; - } } diff --git a/src/Model/Photo.php b/src/Model/Photo.php index 10545eee88..4700db6f50 100644 --- a/src/Model/Photo.php +++ b/src/Model/Photo.php @@ -229,8 +229,8 @@ class Photo return DBA::toArray( DBA::p( - "SELECT `resource-id`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`filename`) AS `filename`, ANY_VALUE(`type`) AS `type`, - min(`scale`) AS `hiq`, max(`scale`) AS `loq`, ANY_VALUE(`desc`) AS `desc`, ANY_VALUE(`created`) AS `created` + "SELECT `resource-id`, MIN(`id`) AS `id`, MIN(`filename`) AS `filename`, MIN(`type`) AS `type`, + min(`scale`) AS `hiq`, max(`scale`) AS `loq`, MIN(`desc`) AS `desc`, MIN(`created`) AS `created` FROM `photo` WHERE `uid` = ? AND NOT `photo-type` IN (?, ?) $sqlExtra GROUP BY `resource-id` $sqlExtra2", $values @@ -597,7 +597,7 @@ class Photo if (!empty($image_url)) { $ret = DI::httpClient()->get($image_url, HttpClientAccept::IMAGE); Logger::debug('Got picture', ['Content-Type' => $ret->getHeader('Content-Type'), 'url' => $image_url]); - $img_str = $ret->getBody(); + $img_str = $ret->getBodyString(); $type = $ret->getContentType(); } else { $img_str = ''; @@ -751,7 +751,7 @@ class Photo if (!DI::config()->get('system', 'no_count', false)) { /// @todo This query needs to be renewed. It is really slow // At this time we just store the data in the cache - $albums = DBA::toArray(DBA::p("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, ANY_VALUE(`created`) AS `created` + $albums = DBA::toArray(DBA::p("SELECT COUNT(DISTINCT `resource-id`) AS `total`, `album`, MIN(`created`) AS `created` FROM `photo` WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra GROUP BY `album` ORDER BY `created` DESC", @@ -762,9 +762,10 @@ class Photo )); } else { // This query doesn't do the count and is much faster - $albums = DBA::toArray(DBA::p("SELECT DISTINCT(`album`), '' AS `total` + $albums = DBA::toArray(DBA::p("SELECT '' AS `total`, `album`, MIN(`created`) AS `created` FROM `photo` USE INDEX (`uid_album_scale_created`) - WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra", + WHERE `uid` = ? AND `photo-type` IN (?, ?, ?) $sql_extra + GROUP BY `album` ORDER BY `created` DESC", $uid, self::DEFAULT, $banner_type, @@ -1047,7 +1048,7 @@ class Photo if (!empty($image_url)) { $ret = DI::httpClient()->get($image_url, HttpClientAccept::IMAGE); Logger::debug('Got picture', ['Content-Type' => $ret->getHeader('Content-Type'), 'url' => $image_url]); - $img_str = $ret->getBody(); + $img_str = $ret->getBodyString(); $type = $ret->getContentType(); } else { $img_str = ''; diff --git a/src/Model/Post/Link.php b/src/Model/Post/Link.php index 76b548baa9..4146efe761 100644 --- a/src/Model/Post/Link.php +++ b/src/Model/Post/Link.php @@ -135,7 +135,7 @@ class Link } $fields = ['mimetype' => $curlResult->getHeader('Content-Type')[0]]; - $img_str = $curlResult->getBody(); + $img_str = $curlResult->getBodyString(); $image = new Image($img_str, Images::getMimeTypeByData($img_str)); if ($image->isValid()) { $fields['mimetype'] = $image->getType(); diff --git a/src/Model/Post/Media.php b/src/Model/Post/Media.php index df05db98d5..afd6ca8383 100644 --- a/src/Model/Post/Media.php +++ b/src/Model/Post/Media.php @@ -208,13 +208,17 @@ class Media $filetype = !empty($media['mimetype']) ? strtolower(current(explode('/', $media['mimetype']))) : ''; if (($media['type'] == self::IMAGE) || ($filetype == 'image')) { - $imagedata = Images::getInfoFromURLCached($media['url']); + $imagedata = Images::getInfoFromURLCached($media['url'], empty($media['description'])); if ($imagedata) { $media['mimetype'] = $imagedata['mime']; $media['size'] = $imagedata['size']; $media['width'] = $imagedata[0]; $media['height'] = $imagedata[1]; $media['blurhash'] = $imagedata['blurhash'] ?? null; + if (!empty($imagedata['description']) && empty($media['description'])) { + $media['description'] = $imagedata['description']; + Logger::debug('Detected text for image', $media); + } } else { Logger::notice('No image data', ['media' => $media]); } diff --git a/src/Model/User.php b/src/Model/User.php index e6cc6ca68c..e1e42e872a 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -874,7 +874,7 @@ class User try { $passwordExposedChecker = new PasswordExposed\PasswordExposedChecker(null, $cache); - return $passwordExposedChecker->passwordExposed($password) === PasswordExposed\PasswordStatus::EXPOSED; + return $passwordExposedChecker->passwordExposed($password) === PasswordExposed\Enums\PasswordStatus::EXPOSED; } catch (Exception $e) { Logger::error('Password Exposed Exception: ' . $e->getMessage(), [ 'code' => $e->getCode(), @@ -1393,7 +1393,7 @@ class User $curlResult = DI::httpClient()->get($photo, HttpClientAccept::IMAGE); if ($curlResult->isSuccess()) { Logger::debug('Got picture', ['Content-Type' => $curlResult->getHeader('Content-Type'), 'url' => $photo]); - $img_str = $curlResult->getBody(); + $img_str = $curlResult->getBodyString(); $type = $curlResult->getContentType(); } else { $img_str = ''; @@ -1563,16 +1563,17 @@ class User /** * Creates a new user based on a minimal set and sends an email to this user * - * @param string $name The user's name - * @param string $email The user's email address - * @param string $nick The user's nick name - * @param string $lang The user's language (default is english) + * @param string $name The user's name + * @param string $email The user's email address + * @param string $nick The user's nick name + * @param string $lang The user's language (default is english) + * @param string $avatar URL to an image to use as avatar (default is to prompt user at first login) * @return bool True, if the user was created successfully * @throws HTTPException\InternalServerErrorException * @throws ErrorException * @throws ImagickException */ - public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT): bool + public static function createMinimal(string $name, string $email, string $nick, string $lang = L10n::DEFAULT, string $avatar = ''): bool { if (empty($name) || empty($email) || @@ -1585,7 +1586,8 @@ class User 'email' => $email, 'nickname' => $nick, 'verified' => 1, - 'language' => $lang + 'language' => $lang, + 'photo' => $avatar ]); $user = $result['user']; @@ -1607,8 +1609,8 @@ class User You may also wish to add some basic information to your default profile (on the "Profiles" page) so that other people can easily find you. - We recommend adding a profile photo, adding some profile "keywords" - (very useful in making new friends) - and perhaps what country you live in; + We recommend adding a profile photo, adding some profile "keywords" + (very useful in making new friends) - and perhaps what country you live in; if you do not wish to be more specific than that. We fully respect your right to privacy, and none of these items are necessary. diff --git a/src/Module/Admin/Federation.php b/src/Module/Admin/Federation.php index 58b4878fc6..af7e433e14 100644 --- a/src/Module/Admin/Federation.php +++ b/src/Module/Admin/Federation.php @@ -97,7 +97,7 @@ class Federation extends BaseAdmin SUM(IFNULL(`local-posts`, 0) + IFNULL(`local-comments`, 0)) AS `posts`, SUM(IFNULL(`active-month-users`, `active-week-users`)) AS `month`, SUM(IFNULL(`active-halfyear-users`, `active-week-users`)) AS `halfyear`, `platform`, - ANY_VALUE(`network`) AS `network`, MAX(`version`) AS `version` + MIN(`network`) AS `network`, MAX(`version`) AS `version` FROM `gserver` WHERE NOT `failed` AND `platform` != ? AND `detection-method` != ? AND NOT `network` IN (?, ?) GROUP BY `platform`", '', GServer::DETECT_MANUAL, Protocol::PHANTOM, Protocol::FEED); while ($gserver = DBA::fetch($gservers)) { diff --git a/src/Module/Contact/MatchInterests.php b/src/Module/Contact/MatchInterests.php index 604a917cbf..ac35244049 100644 --- a/src/Module/Contact/MatchInterests.php +++ b/src/Module/Contact/MatchInterests.php @@ -132,7 +132,7 @@ class MatchInterests extends BaseModule } } - $entries = $this->parseContacts(json_decode($result->getBody()), $entries, $limit); + $entries = $this->parseContacts(json_decode($result->getBodyString()), $entries, $limit); } if (empty($entries)) { diff --git a/src/Module/Conversation/Community.php b/src/Module/Conversation/Community.php index f00f633149..cdb4ddaa23 100644 --- a/src/Module/Conversation/Community.php +++ b/src/Module/Conversation/Community.php @@ -132,8 +132,8 @@ class Community extends Timeline $pager = new BoundariesPager( $this->l10n, $this->args->getQueryString(), - $items[0]['received'], - $items[count($items) - 1]['received'], + $items[array_key_first($items)]['received'], + $items[array_key_last($items)]['received'], $this->itemsPerPage ); diff --git a/src/Module/Magic.php b/src/Module/Magic.php index aa7a75aa70..7b60299e20 100644 --- a/src/Module/Magic.php +++ b/src/Module/Magic.php @@ -155,7 +155,7 @@ class Magic extends BaseModule System::externalRedirect($dest); } - $j = json_decode($curlResult->getBody(), true); + $j = json_decode($curlResult->getBodyString(), true); if (empty($j) || !$j['success']) { $this->logger->notice('Invalid JSON, redirecting to destination.', ['json' => $j, 'dest' => $dest]); $this->app->redirect($dest); diff --git a/src/Module/OStatus/PubSubHubBub.php b/src/Module/OStatus/PubSubHubBub.php index 431d603ee0..e4cc5d7209 100644 --- a/src/Module/OStatus/PubSubHubBub.php +++ b/src/Module/OStatus/PubSubHubBub.php @@ -154,7 +154,7 @@ class PubSubHubBub extends \Friendica\BaseModule $separator = parse_url($hub_callback, PHP_URL_QUERY) === null ? '?' : '&'; $fetchResult = $this->httpClient->fetchFull($hub_callback . $separator . $params); - $body = $fetchResult->getBody(); + $body = $fetchResult->getBodyString(); $returnCode = $fetchResult->getReturnCode(); // give up if the HTTP return code wasn't a success (2xx) diff --git a/src/Module/OStatus/Subscribe.php b/src/Module/OStatus/Subscribe.php index 798e8342c2..cee49d5b94 100644 --- a/src/Module/OStatus/Subscribe.php +++ b/src/Module/OStatus/Subscribe.php @@ -96,7 +96,7 @@ class Subscribe extends \Friendica\BaseModule return $o . $this->t('Couldn\'t fetch friends for contact.'); } - $friends = $curlResult->getBody(); + $friends = $curlResult->getBodyString(); if (empty($friends)) { $this->pConfig->delete($uid, 'ostatus', 'legacy_contact'); return $o . $this->t('Couldn\'t fetch following contacts.'); diff --git a/src/Module/Profile/Photos.php b/src/Module/Profile/Photos.php index f80c63d1a4..8b915a4eba 100644 --- a/src/Module/Profile/Photos.php +++ b/src/Module/Profile/Photos.php @@ -322,12 +322,12 @@ class Photos extends \Friendica\Module\BaseProfile $photos = $this->database->toArray($this->database->p( "SELECT `resource-id`, - ANY_VALUE(`id`) AS `id`, - ANY_VALUE(`filename`) AS `filename`, - ANY_VALUE(`type`) AS `type`, - ANY_VALUE(`album`) AS `album`, - max(`scale`) AS `scale`, - ANY_VALUE(`created`) AS `created` + MIN(`id`) AS `id`, + MIN(`filename`) AS `filename`, + MIN(`type`) AS `type`, + MIN(`album`) AS `album`, + MAX(`scale`) AS `scale`, + MIN(`created`) AS `created` FROM `photo` WHERE `uid` = ? AND `photo-type` = ? diff --git a/src/Module/Proxy.php b/src/Module/Proxy.php index a4a140e47c..0eb95d8a3f 100644 --- a/src/Module/Proxy.php +++ b/src/Module/Proxy.php @@ -85,7 +85,7 @@ class Proxy extends BaseModule // Fetch the content with the local user try { $fetchResult = HTTPSignature::fetchRaw($request['url'], DI::userSession()->getLocalUserId(), [HttpClientOptions::ACCEPT_CONTENT => [HttpClientAccept::IMAGE], 'timeout' => 10]); - $img_str = $fetchResult->getBody(); + $img_str = $fetchResult->getBodyString(); if (!$fetchResult->isSuccess() || empty($img_str)) { Logger::notice('Error fetching image', ['image' => $request['url'], 'return' => $fetchResult->getReturnCode(), 'empty' => empty($img_str)]); diff --git a/src/Network/HTTPClient/Capability/ICanHandleHttpResponses.php b/src/Network/HTTPClient/Capability/ICanHandleHttpResponses.php index e5de3e561b..68c8eda2d8 100644 --- a/src/Network/HTTPClient/Capability/ICanHandleHttpResponses.php +++ b/src/Network/HTTPClient/Capability/ICanHandleHttpResponses.php @@ -97,10 +97,9 @@ interface ICanHandleHttpResponses /** * Getter for body * - * @see MessageInterface::getBody() * @return string */ - public function getBody(); + public function getBodyString(); /** * @return boolean diff --git a/src/Network/HTTPClient/Client/HttpClient.php b/src/Network/HTTPClient/Client/HttpClient.php index 9d0638a8ef..64d0b0a235 100644 --- a/src/Network/HTTPClient/Client/HttpClient.php +++ b/src/Network/HTTPClient/Client/HttpClient.php @@ -73,7 +73,7 @@ class HttpClient implements ICanSendHttpRequests throw new \InvalidArgumentException('Unable to retrieve the host in URL: ' . $url); } - if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A + DNS_AAAA)) { + if(!filter_var($host, FILTER_VALIDATE_IP) && !@dns_get_record($host . '.', DNS_A) && !@dns_get_record($host . '.', DNS_AAAA)) { $this->logger->debug('URL cannot be resolved.', ['url' => $url]); $this->profiler->stopRecording(); return CurlResult::createErrorCurl($this->logger, $url); @@ -271,7 +271,7 @@ class HttpClient implements ICanSendHttpRequests { $ret = $this->fetchFull($url, $accept_content, $timeout, $cookiejar); - return $ret->getBody(); + return $ret->getBodyString(); } /** diff --git a/src/Network/HTTPClient/Response/CurlResult.php b/src/Network/HTTPClient/Response/CurlResult.php index 5ebebda92a..561c8c47ab 100644 --- a/src/Network/HTTPClient/Response/CurlResult.php +++ b/src/Network/HTTPClient/Response/CurlResult.php @@ -330,7 +330,7 @@ class CurlResult implements ICanHandleHttpResponses } /** {@inheritDoc} */ - public function getBody(): string + public function getBodyString(): string { return $this->body; } diff --git a/src/Network/HTTPClient/Response/GuzzleResponse.php b/src/Network/HTTPClient/Response/GuzzleResponse.php index 1b79126159..d277f2a8df 100644 --- a/src/Network/HTTPClient/Response/GuzzleResponse.php +++ b/src/Network/HTTPClient/Response/GuzzleResponse.php @@ -163,8 +163,7 @@ class GuzzleResponse extends Response implements ICanHandleHttpResponses, Respon return $this->isTimeout; } - /// @todo - fix mismatching use of "getBody()" as string here and parent "getBody()" as streaminterface - public function getBody(): string + public function getBodyString(): string { return (string) parent::getBody(); } diff --git a/src/Network/Probe.php b/src/Network/Probe.php index a49c83f991..fc5125f259 100644 --- a/src/Network/Probe.php +++ b/src/Network/Probe.php @@ -225,7 +225,7 @@ class Probe $curlResult = DI::httpClient()->get($ssl_url, HttpClientAccept::XRD_XML, [HttpClientOptions::TIMEOUT => $xrd_timeout]); $ssl_connection_error = ($curlResult->getErrorNumber() == CURLE_COULDNT_CONNECT) || ($curlResult->getReturnCode() == 0); if ($curlResult->isSuccess()) { - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); $xrd = XML::parseString($xml, true); if (!empty($url)) { $host_url = 'https://' . $host; @@ -250,7 +250,7 @@ class Probe return []; } - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); $xrd = XML::parseString($xml, true); $host_url = 'http://'.$host; } @@ -426,7 +426,7 @@ class Probe if (!empty($data['baseurl']) && empty($data['gsid'])) { $data['gsid'] = GServer::getID($data['baseurl']); - } + } // Ensure that local connections always are DFRN if (($network == '') && ($data['network'] != Protocol::PHANTOM) && (self::ownHost($data['baseurl'] ?? '') || self::ownHost($data['url']))) { @@ -459,7 +459,7 @@ class Probe return false; } - $body = $curlResult->getBody(); + $body = $curlResult->getBodyString(); if (empty($body)) { return false; } @@ -865,7 +865,7 @@ class Probe if ($curlResult->isTimeout()) { return $data; } - $content = $curlResult->getBody(); + $content = $curlResult->getBodyString(); if (!$content) { return $data; } @@ -971,7 +971,7 @@ class Probe self::$isTimeout = true; return []; } - $data = $curlResult->getBody(); + $data = $curlResult->getBodyString(); $webfinger = json_decode($data, true); if (!empty($webfinger)) { @@ -1040,7 +1040,7 @@ class Probe self::$isTimeout = true; return $data; } - $content = $curlResult->getBody(); + $content = $curlResult->getBodyString(); if (!$content) { Logger::info('Empty body', ['url' => $noscrape_url]); return $data; @@ -1303,7 +1303,7 @@ class Probe self::$isTimeout = true; return []; } - $content = $curlResult->getBody(); + $content = $curlResult->getBodyString(); if (empty($content)) { return []; } @@ -1580,7 +1580,7 @@ class Probe return $short ? false : []; } Logger::debug('Fetched public key', ['Content-Type' => $curlResult->getHeader('Content-Type'), 'url' => $pubkey]); - $pubkey = $curlResult->getBody(); + $pubkey = $curlResult->getBodyString(); } try { @@ -1612,7 +1612,7 @@ class Probe self::$isTimeout = true; return []; } - $feed = $curlResult->getBody(); + $feed = $curlResult->getBodyString(); $feed_data = Feed::import($feed); if (!$feed_data) { return []; @@ -1660,12 +1660,12 @@ class Probe private static function pumpioProfileData(string $profile_link, string $baseurl): array { $curlResult = DI::httpClient()->get($profile_link, HttpClientAccept::HTML); - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { + if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) { return []; } $doc = new DOMDocument(); - if (!@$doc->loadHTML($curlResult->getBody())) { + if (!@$doc->loadHTML($curlResult->getBodyString())) { return []; } @@ -1887,7 +1887,7 @@ class Probe return []; } - $feed = $curlResult->getBody(); + $feed = $curlResult->getBodyString(); $feed_data = Feed::import($feed); if (!$feed_data) { @@ -2112,8 +2112,8 @@ class Probe $curlResult = DI::httpClient()->get($gserver['noscrape'] . '/' . $data['nick'], HttpClientAccept::JSON); - if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { - $noscrape = json_decode($curlResult->getBody(), true); + if ($curlResult->isSuccess() && !empty($curlResult->getBodyString())) { + $noscrape = json_decode($curlResult->getBodyString(), true); if (!empty($noscrape) && !empty($noscrape['updated'])) { return DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL); } @@ -2187,12 +2187,12 @@ class Probe { // Search for the newest entry in the feed $curlResult = DI::httpClient()->get($data['poll'], HttpClientAccept::ATOM_XML); - if (!$curlResult->isSuccess() || !$curlResult->getBody()) { + if (!$curlResult->isSuccess() || !$curlResult->getBodyString()) { return ''; } $doc = new DOMDocument(); - @$doc->loadXML($curlResult->getBody()); + @$doc->loadXML($curlResult->getBodyString()); $xpath = new DOMXPath($doc); $xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom'); diff --git a/src/Protocol/ActivityPub/Processor.php b/src/Protocol/ActivityPub/Processor.php index 87ebbe1ee2..593c1e7836 100644 --- a/src/Protocol/ActivityPub/Processor.php +++ b/src/Protocol/ActivityPub/Processor.php @@ -614,7 +614,7 @@ class Processor } if ($curlResult->isSuccess()) { - $object = json_decode($curlResult->getBody(), true); + $object = json_decode($curlResult->getBodyString(), true); if (!empty($object)) { $activity = JsonLD::compact($object); if (JsonLD::fetchElement($activity, '@type') == 'as:Tombstone') { @@ -1584,7 +1584,7 @@ class Processor return ''; } - $body = $curlResult->getBody(); + $body = $curlResult->getBodyString(); if (!$curlResult->isSuccess() || empty($body)) { if (in_array($curlResult->getReturnCode(), [403, 404, 406, 410])) { return null; diff --git a/src/Protocol/DFRN.php b/src/Protocol/DFRN.php index b358796ce7..4d44b8a40f 100644 --- a/src/Protocol/DFRN.php +++ b/src/Protocol/DFRN.php @@ -1012,7 +1012,7 @@ class DFRN $content_type = ($public_batch ? 'application/magic-envelope+xml' : 'application/json'); $postResult = DI::httpClient()->post($dest_url, $envelope, ['Content-Type' => $content_type]); - $xml = $postResult->getBody(); + $xml = $postResult->getBodyString(); $curl_stat = $postResult->getReturnCode(); if (!empty($contact['gsid']) && ($postResult->isTimeout() || empty($curl_stat))) { diff --git a/src/Protocol/OStatus.php b/src/Protocol/OStatus.php index 061a27b372..fa93b0e827 100644 --- a/src/Protocol/OStatus.php +++ b/src/Protocol/OStatus.php @@ -736,7 +736,7 @@ class OStatus $stored = false; $curlResult = DI::httpClient()->get($related, HttpClientAccept::ATOM_XML); - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { + if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) { return; } @@ -745,12 +745,12 @@ class OStatus if ($curlResult->inHeader('Content-Type') && in_array('application/atom+xml', $curlResult->getHeader('Content-Type'))) { Logger::info('Directly fetched XML for URI ' . $related_uri); - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); } if ($xml == '') { $doc = new DOMDocument(); - if (!@$doc->loadHTML($curlResult->getBody())) { + if (!@$doc->loadHTML($curlResult->getBodyString())) { return; } $xpath = new DOMXPath($doc); @@ -770,7 +770,7 @@ class OStatus if ($curlResult->isSuccess()) { Logger::info('Fetched XML for URI ' . $related_uri); - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); } } } @@ -782,7 +782,7 @@ class OStatus if ($curlResult->isSuccess()) { Logger::info('GNU Social workaround to fetch XML for URI ' . $related_uri); - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); } } @@ -793,7 +793,7 @@ class OStatus if ($curlResult->isSuccess()) { Logger::info('GNU Social workaround 2 to fetch XML for URI ' . $related_uri); - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); } } diff --git a/src/Security/ExAuth.php b/src/Security/ExAuth.php index 7aac5cad79..eda2f398e6 100644 --- a/src/Security/ExAuth.php +++ b/src/Security/ExAuth.php @@ -250,7 +250,7 @@ class ExAuth return false; } - $json = @json_decode($curlResult->getBody()); + $json = @json_decode($curlResult->getBodyString()); if (!is_object($json)) { return false; } diff --git a/src/Util/HTTPSignature.php b/src/Util/HTTPSignature.php index c0f596e050..01f75776f2 100644 --- a/src/Util/HTTPSignature.php +++ b/src/Util/HTTPSignature.php @@ -433,12 +433,12 @@ class HTTPSignature return []; } - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { + if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) { Logger::debug('Fetching was unsuccessful', ['url' => $request, 'return-code' => $curlResult->getReturnCode(), 'error-number' => $curlResult->getErrorNumber(), 'error' => $curlResult->getError()]); return []; } - $content = json_decode($curlResult->getBody(), true); + $content = json_decode($curlResult->getBodyString(), true); if (empty($content) || !is_array($content)) { return []; } diff --git a/src/Util/Images.php b/src/Util/Images.php index b44b1fb8f5..e5b8afbb54 100644 --- a/src/Util/Images.php +++ b/src/Util/Images.php @@ -21,6 +21,7 @@ namespace Friendica\Util; +use Friendica\Core\Hook; use Friendica\Core\Logger; use Friendica\DI; use Friendica\Model\Photo; @@ -181,10 +182,11 @@ class Images * Gets info array from given URL, cached data has priority * * @param string $url + * @param bool $ocr * @return array Info * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function getInfoFromURLCached(string $url): array + public static function getInfoFromURLCached(string $url, bool $ocr = false): array { $data = []; @@ -192,12 +194,12 @@ class Images return $data; } - $cacheKey = 'getInfoFromURL:' . sha1($url); + $cacheKey = 'getInfoFromURL:' . sha1($url . $ocr); $data = DI::cache()->get($cacheKey); if (empty($data) || !is_array($data)) { - $data = self::getInfoFromURL($url); + $data = self::getInfoFromURL($url, $ocr); DI::cache()->set($cacheKey, $data); } @@ -209,10 +211,11 @@ class Images * Gets info from URL uncached * * @param string $url + * @param bool $ocr * @return array Info array * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function getInfoFromURL(string $url): array + public static function getInfoFromURL(string $url, bool $ocr = false): array { $data = []; @@ -257,6 +260,14 @@ class Images if ($image->isValid()) { $data['blurhash'] = $image->getBlurHash(); + + if ($ocr) { + $media = ['img_str' => $img_str]; + Hook::callAll('ocr-detection', $media); + if (!empty($media['description'])) { + $data['description'] = $media['description']; + } + } } $data['size'] = $filesize; diff --git a/src/Util/ParseUrl.php b/src/Util/ParseUrl.php index 684f54c402..184a02ae75 100644 --- a/src/Util/ParseUrl.php +++ b/src/Util/ParseUrl.php @@ -238,7 +238,7 @@ class ParseUrl } $curlResult = DI::httpClient()->get($url, HttpClientAccept::HTML, [HttpClientOptions::CONTENT_LENGTH => 1000000]); - if (!$curlResult->isSuccess() || empty($curlResult->getBody())) { + if (!$curlResult->isSuccess() || empty($curlResult->getBodyString())) { Logger::info('Empty body or error when fetching', ['url' => $url, 'success' => $curlResult->isSuccess(), 'code' => $curlResult->getReturnCode()]); return $siteinfo; } @@ -252,7 +252,7 @@ class ParseUrl } } - $body = $curlResult->getBody(); + $body = $curlResult->getBodyString(); if ($do_oembed) { $oembed_data = OEmbed::fetchURL($url, false, false); diff --git a/src/Worker/CheckRelMeProfileLink.php b/src/Worker/CheckRelMeProfileLink.php index e316371a58..a6bfc9b4c4 100644 --- a/src/Worker/CheckRelMeProfileLink.php +++ b/src/Worker/CheckRelMeProfileLink.php @@ -70,7 +70,7 @@ class CheckRelMeProfileLink return; } - $content = $curlResult->getBody(); + $content = $curlResult->getBodyString(); if (!$content) { Logger::notice('Empty body of the fetched homepage link). Cannot verify the relation to profile of UID %s.', ['uid' => $uid, 'owner homepage' => $owner['homepage']]); return; diff --git a/src/Worker/OnePoll.php b/src/Worker/OnePoll.php index 9f342a30a7..a379c1a371 100644 --- a/src/Worker/OnePoll.php +++ b/src/Worker/OnePoll.php @@ -172,7 +172,7 @@ class OnePoll return false; } - $xml = $curlResult->getBody(); + $xml = $curlResult->getBodyString(); if (empty($xml)) { Logger::notice('Empty content', ['id' => $contact['id'], 'url' => $contact['poll']]); return false; diff --git a/src/Worker/UpdateServerPeers.php b/src/Worker/UpdateServerPeers.php index e6998c446d..dd08f5cb40 100644 --- a/src/Worker/UpdateServerPeers.php +++ b/src/Worker/UpdateServerPeers.php @@ -45,12 +45,12 @@ class UpdateServerPeers } $ret = DI::httpClient()->get($url . '/api/v1/instance/peers', HttpClientAccept::JSON); - if (!$ret->isSuccess() || empty($ret->getBody())) { + if (!$ret->isSuccess() || empty($ret->getBodyString())) { Logger::info('Server is not reachable or does not offer the "peers" endpoint', ['url' => $url]); return; } - $peers = json_decode($ret->getBody()); + $peers = json_decode($ret->getBodyString()); if (empty($peers) || !is_array($peers)) { Logger::info('Server does not have any peers listed', ['url' => $url]); return; diff --git a/tests/src/Network/HTTPClient/Response/CurlResultTest.php b/tests/src/Network/HTTPClient/Response/CurlResultTest.php index e7459246e7..d1935ddc83 100644 --- a/tests/src/Network/HTTPClient/Response/CurlResultTest.php +++ b/tests/src/Network/HTTPClient/Response/CurlResultTest.php @@ -47,7 +47,7 @@ class CurlResultTest extends TestCase self::assertFalse($curlResult->isTimeout()); self::assertFalse($curlResult->isRedirectUrl()); self::assertSame($headerArray, $curlResult->getHeaders()); - self::assertSame($body, $curlResult->getBody()); + self::assertSame($body, $curlResult->getBodyString()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local', $curlResult->getUrl()); self::assertSame('https://test.local', $curlResult->getRedirectUrl()); @@ -76,7 +76,7 @@ class CurlResultTest extends TestCase self::assertFalse($curlResult->isTimeout()); self::assertTrue($curlResult->isRedirectUrl()); self::assertSame($headerArray, $curlResult->getHeaders()); - self::assertSame($body, $curlResult->getBody()); + self::assertSame($body, $curlResult->getBodyString()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local/test/it', $curlResult->getUrl()); self::assertSame('https://test.other/test/it', $curlResult->getRedirectUrl()); @@ -103,7 +103,7 @@ class CurlResultTest extends TestCase self::assertTrue($curlResult->isTimeout()); self::assertFalse($curlResult->isRedirectUrl()); self::assertSame($headerArray, $curlResult->getHeaders()); - self::assertSame($body, $curlResult->getBody()); + self::assertSame($body, $curlResult->getBodyString()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local/test/it', $curlResult->getRedirectUrl()); self::assertSame('Tested error', $curlResult->getError()); @@ -131,7 +131,7 @@ class CurlResultTest extends TestCase self::assertFalse($curlResult->isTimeout()); self::assertTrue($curlResult->isRedirectUrl()); self::assertSame($headerArray, $curlResult->getHeaders()); - self::assertSame($body, $curlResult->getBody()); + self::assertSame($body, $curlResult->getBodyString()); self::assertSame('text/html; charset=utf-8', $curlResult->getContentType()); self::assertSame('https://test.local/test/it?key=value', $curlResult->getUrl()); self::assertSame('https://test.other/some/?key=value', $curlResult->getRedirectUrl()); diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index 9c7e7a42d6..6caf64b1fd 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -953,7 +953,7 @@ msgstr "" msgid "All pending post updates are done." msgstr "" -#: src/Console/User.php:158 src/Console/User.php:245 +#: src/Console/User.php:158 src/Console/User.php:246 msgid "Enter user nickname: " msgstr "" @@ -980,44 +980,48 @@ msgstr "" msgid "Password changed." msgstr "" -#: src/Console/User.php:237 +#: src/Console/User.php:238 msgid "Enter user name: " msgstr "" -#: src/Console/User.php:253 +#: src/Console/User.php:254 msgid "Enter user email address: " msgstr "" -#: src/Console/User.php:261 +#: src/Console/User.php:262 msgid "Enter a language (optional): " msgstr "" -#: src/Console/User.php:286 +#: src/Console/User.php:267 +msgid "Enter URL of an image to use as avatar (optional): " +msgstr "" + +#: src/Console/User.php:292 msgid "User is not pending." msgstr "" -#: src/Console/User.php:318 +#: src/Console/User.php:324 msgid "User has already been marked for deletion." msgstr "" -#: src/Console/User.php:323 +#: src/Console/User.php:329 #, php-format msgid "Type \"yes\" to delete %s" msgstr "" -#: src/Console/User.php:325 +#: src/Console/User.php:331 msgid "Deletion aborted." msgstr "" -#: src/Console/User.php:450 +#: src/Console/User.php:456 msgid "Enter category: " msgstr "" -#: src/Console/User.php:460 +#: src/Console/User.php:466 msgid "Enter key: " msgstr "" -#: src/Console/User.php:494 +#: src/Console/User.php:500 msgid "Enter value: " msgstr "" @@ -1377,7 +1381,7 @@ msgstr "" msgid "Public post" msgstr "" -#: src/Content/Conversation.php:426 src/Content/Widget/VCard.php:131 +#: src/Content/Conversation.php:426 src/Content/Widget/VCard.php:127 #: src/Model/Profile.php:483 src/Module/Admin/Logs/View.php:92 #: src/Module/Post/Edit.php:181 msgid "Message" @@ -2220,7 +2224,7 @@ msgstr "" msgid "The end" msgstr "" -#: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:127 +#: src/Content/Text/HTML.php:859 src/Content/Widget/VCard.php:123 #: src/Model/Profile.php:477 src/Module/Contact/Profile.php:471 msgid "Follow" msgstr "" @@ -2430,17 +2434,17 @@ msgstr "" msgid "Mention" msgstr "" -#: src/Content/Widget/VCard.php:120 src/Model/Profile.php:380 +#: src/Content/Widget/VCard.php:116 src/Model/Profile.php:380 #: src/Module/Contact/Profile.php:408 src/Module/Profile/Profile.php:199 msgid "XMPP:" msgstr "" -#: src/Content/Widget/VCard.php:121 src/Model/Profile.php:381 +#: src/Content/Widget/VCard.php:117 src/Model/Profile.php:381 #: src/Module/Contact/Profile.php:410 src/Module/Profile/Profile.php:203 msgid "Matrix:" msgstr "" -#: src/Content/Widget/VCard.php:122 src/Model/Event.php:82 +#: src/Content/Widget/VCard.php:118 src/Model/Event.php:82 #: src/Model/Event.php:109 src/Model/Event.php:471 src/Model/Event.php:963 #: src/Model/Profile.php:375 src/Module/Contact/Profile.php:406 #: src/Module/Directory.php:147 src/Module/Notifications/Introductions.php:187 @@ -2448,7 +2452,7 @@ msgstr "" msgid "Location:" msgstr "" -#: src/Content/Widget/VCard.php:125 src/Model/Profile.php:490 +#: src/Content/Widget/VCard.php:121 src/Model/Profile.php:490 #: src/Module/Notifications/Introductions.php:201 msgid "Network:" msgstr "" @@ -3817,9 +3821,9 @@ msgid "" "\t\tYou may also wish to add some basic information to your default profile\n" "\t\t(on the \"Profiles\" page) so that other people can easily find you.\n" "\n" -"\t\tWe recommend adding a profile photo, adding some profile \"keywords\" \n" +"\t\tWe recommend adding a profile photo, adding some profile \"keywords\"\n" "\t\t(very useful in making new friends) - and perhaps what country you live " -"in; \n" +"in;\n" "\t\tif you do not wish to be more specific than that.\n" "\n" "\t\tWe fully respect your right to privacy, and none of these items are " diff --git a/view/templates/field_checkbox.tpl b/view/templates/field_checkbox.tpl index 4bdb5a0912..caf7a050cd 100644 --- a/view/templates/field_checkbox.tpl +++ b/view/templates/field_checkbox.tpl @@ -1,7 +1,7 @@
- + {{if $field.3}} {{$field.3 nofilter}} {{/if}} diff --git a/view/templates/field_combobox.tpl b/view/templates/field_combobox.tpl index b62bf2dbac..94b2853110 100644 --- a/view/templates/field_combobox.tpl +++ b/view/templates/field_combobox.tpl @@ -1,12 +1,12 @@ -
- +
+ {{* html5 don't work on Chrome, Safari and IE9 {{foreach $field.4 as $opt=>$val}} *}} - +