[Web] Update composer deps

master
andryyy 2021-06-23 08:05:09 +02:00
parent d156a93a84
commit 5035e5bb42
No known key found for this signature in database
GPG Key ID: 8EC34FF2794E25EF
136 changed files with 3020 additions and 805 deletions

View File

@ -144,16 +144,16 @@
}, },
{ {
"name": "directorytree/ldaprecord", "name": "directorytree/ldaprecord",
"version": "v2.4.6", "version": "v2.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/DirectoryTree/LdapRecord.git", "url": "https://github.com/DirectoryTree/LdapRecord.git",
"reference": "824a49feae4da52a522b3ec60ecad508b8f4ed23" "reference": "ff7a92615fdc3f8b7f3d347c2847ce7ce06db287"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/824a49feae4da52a522b3ec60ecad508b8f4ed23", "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/ff7a92615fdc3f8b7f3d347c2847ce7ce06db287",
"reference": "824a49feae4da52a522b3ec60ecad508b8f4ed23", "reference": "ff7a92615fdc3f8b7f3d347c2847ce7ce06db287",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -161,15 +161,15 @@
"ext-ldap": "*", "ext-ldap": "*",
"illuminate/contracts": "^5.0|^6.0|^7.0|^8.0", "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0",
"nesbot/carbon": "^1.0|^2.0", "nesbot/carbon": "^1.0|^2.0",
"php": ">=7.2", "php": ">=7.3",
"psr/log": "^1.0", "psr/log": "^1.0",
"psr/simple-cache": "^1.0", "psr/simple-cache": "^1.0",
"tightenco/collect": "^5.6|^6.0|^7.0|^8.0" "tightenco/collect": "^5.6|^6.0|^7.0|^8.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"mockery/mockery": "^1.0", "mockery/mockery": "^1.0",
"phpunit/phpunit": "^8.0" "phpunit/phpunit": "^8.0",
"spatie/ray": "^1.24"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
@ -213,20 +213,20 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-05-11T13:29:46+00:00" "time": "2021-06-06T18:51:41+00:00"
}, },
{ {
"name": "illuminate/contracts", "name": "illuminate/contracts",
"version": "v8.42.1", "version": "v8.48.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/contracts.git", "url": "https://github.com/illuminate/contracts.git",
"reference": "68036b4fb17ad40a599323bda3f2c0845c8100d8" "reference": "199fcedc161ba4a0b83feaddc4629f395dbf1641"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/68036b4fb17ad40a599323bda3f2c0845c8100d8", "url": "https://api.github.com/repos/illuminate/contracts/zipball/199fcedc161ba4a0b83feaddc4629f395dbf1641",
"reference": "68036b4fb17ad40a599323bda3f2c0845c8100d8", "reference": "199fcedc161ba4a0b83feaddc4629f395dbf1641",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -261,7 +261,7 @@
"issues": "https://github.com/laravel/framework/issues", "issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework" "source": "https://github.com/laravel/framework"
}, },
"time": "2021-05-18T12:49:19+00:00" "time": "2021-06-01T14:53:38+00:00"
}, },
{ {
"name": "matthiasmullie/minify", "name": "matthiasmullie/minify",
@ -446,16 +446,16 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "2.48.0", "version": "2.49.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "d3c447f21072766cddec3522f9468a5849a76147" "reference": "93d9db91c0235c486875d22f1e08b50bdf3e6eee"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d3c447f21072766cddec3522f9468a5849a76147", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/93d9db91c0235c486875d22f1e08b50bdf3e6eee",
"reference": "d3c447f21072766cddec3522f9468a5849a76147", "reference": "93d9db91c0235c486875d22f1e08b50bdf3e6eee",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -535,7 +535,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-05-07T10:08:30+00:00" "time": "2021-06-02T07:31:40+00:00"
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
@ -675,16 +675,16 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.4.1", "version": "v6.5.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d" "reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9256f12d8fb0cd0500f93b19e18c356906cbed3d", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d", "reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -739,7 +739,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.1" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0"
}, },
"funding": [ "funding": [
{ {
@ -747,7 +747,7 @@
"type": "github" "type": "github"
} }
], ],
"time": "2021-04-29T12:25:04+00:00" "time": "2021-06-16T14:33:43+00:00"
}, },
{ {
"name": "psr/container", "name": "psr/container",
@ -1024,17 +1024,84 @@
"time": "2017-04-19T22:01:50+00:00" "time": "2017-04-19T22:01:50+00:00"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/deprecation-contracts",
"version": "v1.22.1", "version": "v2.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1" "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.php"
]
},
"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": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2021-03-23T23:28:01+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.23.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
"reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1046,7 +1113,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.22-dev" "dev-main": "1.23-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1085,7 +1152,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0"
}, },
"funding": [ "funding": [
{ {
@ -1101,20 +1168,20 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-01-22T09:19:47+00:00" "time": "2021-05-27T09:27:20+00:00"
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.22.1", "version": "v1.23.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1123,7 +1190,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.22-dev" "dev-main": "1.23-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1168,7 +1235,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.0"
}, },
"funding": [ "funding": [
{ {
@ -1184,24 +1251,25 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-01-07T16:49:33+00:00" "time": "2021-02-19T12:13:01+00:00"
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v5.2.9", "version": "v5.3.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "61af68dba333e2d376a325a29c2a3f2a605b4876" "reference": "7e2603bcc598e14804c4d2359d8dc4ee3c40391b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/61af68dba333e2d376a325a29c2a3f2a605b4876", "url": "https://api.github.com/repos/symfony/translation/zipball/7e2603bcc598e14804c4d2359d8dc4ee3c40391b",
"reference": "61af68dba333e2d376a325a29c2a3f2a605b4876", "reference": "7e2603bcc598e14804c4d2359d8dc4ee3c40391b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.2.5", "php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.15", "symfony/polyfill-php80": "^1.15",
"symfony/translation-contracts": "^2.3" "symfony/translation-contracts": "^2.3"
@ -1224,6 +1292,7 @@
"symfony/finder": "^4.4|^5.0", "symfony/finder": "^4.4|^5.0",
"symfony/http-kernel": "^5.0", "symfony/http-kernel": "^5.0",
"symfony/intl": "^4.4|^5.0", "symfony/intl": "^4.4|^5.0",
"symfony/polyfill-intl-icu": "^1.21",
"symfony/service-contracts": "^1.1.2|^2", "symfony/service-contracts": "^1.1.2|^2",
"symfony/yaml": "^4.4|^5.0" "symfony/yaml": "^4.4|^5.0"
}, },
@ -1261,7 +1330,7 @@
"description": "Provides tools to internationalize your application", "description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/translation/tree/v5.2.9" "source": "https://github.com/symfony/translation/tree/v5.3.2"
}, },
"funding": [ "funding": [
{ {
@ -1277,7 +1346,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-05-16T13:07:46+00:00" "time": "2021-06-06T09:51:56+00:00"
}, },
{ {
"name": "symfony/translation-contracts", "name": "symfony/translation-contracts",
@ -1359,16 +1428,16 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v5.2.8", "version": "v5.3.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "d693200a73fae179d27f8f1b16b4faf3e8569eba" "reference": "905a22c68b292ffb6f20d7636c36b220d1fba5ae"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/d693200a73fae179d27f8f1b16b4faf3e8569eba", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/905a22c68b292ffb6f20d7636c36b220d1fba5ae",
"reference": "d693200a73fae179d27f8f1b16b4faf3e8569eba", "reference": "905a22c68b292ffb6f20d7636c36b220d1fba5ae",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1427,7 +1496,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v5.2.8" "source": "https://github.com/symfony/var-dumper/tree/v5.3.2"
}, },
"funding": [ "funding": [
{ {
@ -1443,7 +1512,7 @@
"type": "tidelift" "type": "tidelift"
} }
], ],
"time": "2021-05-07T13:42:21+00:00" "time": "2021-06-06T09:51:56+00:00"
}, },
{ {
"name": "tightenco/collect", "name": "tightenco/collect",

View File

@ -66,12 +66,12 @@ private static $installed = array (
), ),
'directorytree/ldaprecord' => 'directorytree/ldaprecord' =>
array ( array (
'pretty_version' => 'v2.4.6', 'pretty_version' => 'v2.5.0',
'version' => '2.4.6.0', 'version' => '2.5.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '824a49feae4da52a522b3ec60ecad508b8f4ed23', 'reference' => 'ff7a92615fdc3f8b7f3d347c2847ce7ce06db287',
), ),
'exorus/php-mime-mail-parser' => 'exorus/php-mime-mail-parser' =>
array ( array (
@ -82,12 +82,12 @@ private static $installed = array (
), ),
'illuminate/contracts' => 'illuminate/contracts' =>
array ( array (
'pretty_version' => 'v8.42.1', 'pretty_version' => 'v8.48.0',
'version' => '8.42.1.0', 'version' => '8.48.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '68036b4fb17ad40a599323bda3f2c0845c8100d8', 'reference' => '199fcedc161ba4a0b83feaddc4629f395dbf1641',
), ),
'matthiasmullie/minify' => 'matthiasmullie/minify' =>
array ( array (
@ -125,12 +125,12 @@ private static $installed = array (
), ),
'nesbot/carbon' => 'nesbot/carbon' =>
array ( array (
'pretty_version' => '2.48.0', 'pretty_version' => '2.49.0',
'version' => '2.48.0.0', 'version' => '2.49.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'd3c447f21072766cddec3522f9468a5849a76147', 'reference' => '93d9db91c0235c486875d22f1e08b50bdf3e6eee',
), ),
'paragonie/random_compat' => 'paragonie/random_compat' =>
array ( array (
@ -152,12 +152,12 @@ private static $installed = array (
), ),
'phpmailer/phpmailer' => 'phpmailer/phpmailer' =>
array ( array (
'pretty_version' => 'v6.4.1', 'pretty_version' => 'v6.5.0',
'version' => '6.4.1.0', 'version' => '6.5.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '9256f12d8fb0cd0500f93b19e18c356906cbed3d', 'reference' => 'a5b5c43e50b7fba655f793ad27303cd74c57363c',
), ),
'psr/container' => 'psr/container' =>
array ( array (
@ -204,32 +204,41 @@ private static $installed = array (
), ),
'reference' => 'cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad', 'reference' => 'cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad',
), ),
'symfony/polyfill-mbstring' => 'symfony/deprecation-contracts' =>
array ( array (
'pretty_version' => 'v1.22.1', 'pretty_version' => 'v2.4.0',
'version' => '1.22.1.0', 'version' => '2.4.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '5232de97ee3b75b0360528dae24e73db49566ab1', 'reference' => '5f38c8804a9e97d23e0c8d63341088cd8a22d627',
),
'symfony/polyfill-mbstring' =>
array (
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
'aliases' =>
array (
),
'reference' => '2df51500adbaebdc4c38dea4c89a2e131c45c8a1',
), ),
'symfony/polyfill-php80' => 'symfony/polyfill-php80' =>
array ( array (
'pretty_version' => 'v1.22.1', 'pretty_version' => 'v1.23.0',
'version' => '1.22.1.0', 'version' => '1.23.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'dc3063ba22c2a1fd2f45ed856374d79114998f91', 'reference' => 'eca0bf41ed421bed1b57c4958bab16aa86b757d0',
), ),
'symfony/translation' => 'symfony/translation' =>
array ( array (
'pretty_version' => 'v5.2.9', 'pretty_version' => 'v5.3.2',
'version' => '5.2.9.0', 'version' => '5.3.2.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '61af68dba333e2d376a325a29c2a3f2a605b4876', 'reference' => '7e2603bcc598e14804c4d2359d8dc4ee3c40391b',
), ),
'symfony/translation-contracts' => 'symfony/translation-contracts' =>
array ( array (
@ -249,12 +258,12 @@ private static $installed = array (
), ),
'symfony/var-dumper' => 'symfony/var-dumper' =>
array ( array (
'pretty_version' => 'v5.2.8', 'pretty_version' => 'v5.3.2',
'version' => '5.2.8.0', 'version' => '5.3.2.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'd693200a73fae179d27f8f1b16b4faf3e8569eba', 'reference' => '905a22c68b292ffb6f20d7636c36b220d1fba5ae',
), ),
'tightenco/collect' => 'tightenco/collect' =>
array ( array (
@ -455,8 +464,11 @@ return $installed[0]['root'];
public static function getRawData() public static function getRawData()
{ {
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
return self::$installed; return self::$installed;
} }
@ -466,6 +478,17 @@ return self::$installed;
public static function getAllRawData()
{
return self::getInstalled();
}

View File

@ -8,6 +8,7 @@ $baseDir = dirname($vendorDir);
return array( return array(
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php', 'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php', '667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php', 'fe62ba7e10580d903cc46d808b5961a4' => $vendorDir . '/tightenco/collect/src/Collect/Support/helpers.php',

View File

@ -9,6 +9,7 @@ class ComposerStaticInit873464e4bd965a3168f133248b1b218b
public static $files = array ( public static $files = array (
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php', 'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php', 'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php', '667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php', 'fe62ba7e10580d903cc46d808b5961a4' => __DIR__ . '/..' . '/tightenco/collect/src/Collect/Support/helpers.php',

View File

@ -140,17 +140,17 @@
}, },
{ {
"name": "directorytree/ldaprecord", "name": "directorytree/ldaprecord",
"version": "v2.4.6", "version": "v2.5.0",
"version_normalized": "2.4.6.0", "version_normalized": "2.5.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/DirectoryTree/LdapRecord.git", "url": "https://github.com/DirectoryTree/LdapRecord.git",
"reference": "824a49feae4da52a522b3ec60ecad508b8f4ed23" "reference": "ff7a92615fdc3f8b7f3d347c2847ce7ce06db287"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/824a49feae4da52a522b3ec60ecad508b8f4ed23", "url": "https://api.github.com/repos/DirectoryTree/LdapRecord/zipball/ff7a92615fdc3f8b7f3d347c2847ce7ce06db287",
"reference": "824a49feae4da52a522b3ec60ecad508b8f4ed23", "reference": "ff7a92615fdc3f8b7f3d347c2847ce7ce06db287",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -158,17 +158,17 @@
"ext-ldap": "*", "ext-ldap": "*",
"illuminate/contracts": "^5.0|^6.0|^7.0|^8.0", "illuminate/contracts": "^5.0|^6.0|^7.0|^8.0",
"nesbot/carbon": "^1.0|^2.0", "nesbot/carbon": "^1.0|^2.0",
"php": ">=7.2", "php": ">=7.3",
"psr/log": "^1.0", "psr/log": "^1.0",
"psr/simple-cache": "^1.0", "psr/simple-cache": "^1.0",
"tightenco/collect": "^5.6|^6.0|^7.0|^8.0" "tightenco/collect": "^5.6|^6.0|^7.0|^8.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "^3.0",
"mockery/mockery": "^1.0", "mockery/mockery": "^1.0",
"phpunit/phpunit": "^8.0" "phpunit/phpunit": "^8.0",
"spatie/ray": "^1.24"
}, },
"time": "2021-05-11T13:29:46+00:00", "time": "2021-06-06T18:51:41+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -216,17 +216,17 @@
}, },
{ {
"name": "illuminate/contracts", "name": "illuminate/contracts",
"version": "v8.42.1", "version": "v8.48.0",
"version_normalized": "8.42.1.0", "version_normalized": "8.48.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/illuminate/contracts.git", "url": "https://github.com/illuminate/contracts.git",
"reference": "68036b4fb17ad40a599323bda3f2c0845c8100d8" "reference": "199fcedc161ba4a0b83feaddc4629f395dbf1641"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/illuminate/contracts/zipball/68036b4fb17ad40a599323bda3f2c0845c8100d8", "url": "https://api.github.com/repos/illuminate/contracts/zipball/199fcedc161ba4a0b83feaddc4629f395dbf1641",
"reference": "68036b4fb17ad40a599323bda3f2c0845c8100d8", "reference": "199fcedc161ba4a0b83feaddc4629f395dbf1641",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -234,7 +234,7 @@
"psr/container": "^1.0", "psr/container": "^1.0",
"psr/simple-cache": "^1.0" "psr/simple-cache": "^1.0"
}, },
"time": "2021-05-18T12:49:19+00:00", "time": "2021-06-01T14:53:38+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -453,17 +453,17 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "2.48.0", "version": "2.49.0",
"version_normalized": "2.48.0.0", "version_normalized": "2.49.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "d3c447f21072766cddec3522f9468a5849a76147" "reference": "93d9db91c0235c486875d22f1e08b50bdf3e6eee"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/d3c447f21072766cddec3522f9468a5849a76147", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/93d9db91c0235c486875d22f1e08b50bdf3e6eee",
"reference": "d3c447f21072766cddec3522f9468a5849a76147", "reference": "93d9db91c0235c486875d22f1e08b50bdf3e6eee",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -482,7 +482,7 @@
"phpunit/phpunit": "^7.5.20 || ^8.5.14", "phpunit/phpunit": "^7.5.20 || ^8.5.14",
"squizlabs/php_codesniffer": "^3.4" "squizlabs/php_codesniffer": "^3.4"
}, },
"time": "2021-05-07T10:08:30+00:00", "time": "2021-06-02T07:31:40+00:00",
"bin": [ "bin": [
"bin/carbon" "bin/carbon"
], ],
@ -687,17 +687,17 @@
}, },
{ {
"name": "phpmailer/phpmailer", "name": "phpmailer/phpmailer",
"version": "v6.4.1", "version": "v6.5.0",
"version_normalized": "6.4.1.0", "version_normalized": "6.5.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/PHPMailer/PHPMailer.git", "url": "https://github.com/PHPMailer/PHPMailer.git",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d" "reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/9256f12d8fb0cd0500f93b19e18c356906cbed3d", "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a5b5c43e50b7fba655f793ad27303cd74c57363c",
"reference": "9256f12d8fb0cd0500f93b19e18c356906cbed3d", "reference": "a5b5c43e50b7fba655f793ad27303cd74c57363c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -722,7 +722,7 @@
"stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
"symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
}, },
"time": "2021-04-29T12:25:04+00:00", "time": "2021-06-16T14:33:43+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -754,7 +754,7 @@
"description": "PHPMailer is a full-featured email creation and transfer class for PHP", "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
"support": { "support": {
"issues": "https://github.com/PHPMailer/PHPMailer/issues", "issues": "https://github.com/PHPMailer/PHPMailer/issues",
"source": "https://github.com/PHPMailer/PHPMailer/tree/v6.4.1" "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.0"
}, },
"funding": [ "funding": [
{ {
@ -1049,18 +1049,88 @@
"install-path": "../soundasleep/html2text" "install-path": "../soundasleep/html2text"
}, },
{ {
"name": "symfony/polyfill-mbstring", "name": "symfony/deprecation-contracts",
"version": "v1.22.1", "version": "v2.4.0",
"version_normalized": "1.22.1.0", "version_normalized": "2.4.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git", "url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1" "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"time": "2021-03-23T23:28:01+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"function.php"
]
},
"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": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"install-path": "../symfony/deprecation-contracts"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.23.0",
"version_normalized": "1.23.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
"reference": "2df51500adbaebdc4c38dea4c89a2e131c45c8a1",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1069,11 +1139,11 @@
"suggest": { "suggest": {
"ext-mbstring": "For best performance" "ext-mbstring": "For best performance"
}, },
"time": "2021-01-22T09:19:47+00:00", "time": "2021-05-27T09:27:20+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.22-dev" "dev-main": "1.23-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1113,7 +1183,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.0"
}, },
"funding": [ "funding": [
{ {
@ -1133,27 +1203,27 @@
}, },
{ {
"name": "symfony/polyfill-php80", "name": "symfony/polyfill-php80",
"version": "v1.22.1", "version": "v1.23.0",
"version_normalized": "1.22.1.0", "version_normalized": "1.23.0.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/polyfill-php80.git", "url": "https://github.com/symfony/polyfill-php80.git",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/eca0bf41ed421bed1b57c4958bab16aa86b757d0",
"reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "reference": "eca0bf41ed421bed1b57c4958bab16aa86b757d0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.1" "php": ">=7.1"
}, },
"time": "2021-01-07T16:49:33+00:00", "time": "2021-02-19T12:13:01+00:00",
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.22-dev" "dev-main": "1.23-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",
@ -1199,7 +1269,7 @@
"shim" "shim"
], ],
"support": { "support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.0"
}, },
"funding": [ "funding": [
{ {
@ -1219,21 +1289,22 @@
}, },
{ {
"name": "symfony/translation", "name": "symfony/translation",
"version": "v5.2.9", "version": "v5.3.2",
"version_normalized": "5.2.9.0", "version_normalized": "5.3.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/translation.git", "url": "https://github.com/symfony/translation.git",
"reference": "61af68dba333e2d376a325a29c2a3f2a605b4876" "reference": "7e2603bcc598e14804c4d2359d8dc4ee3c40391b"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/translation/zipball/61af68dba333e2d376a325a29c2a3f2a605b4876", "url": "https://api.github.com/repos/symfony/translation/zipball/7e2603bcc598e14804c4d2359d8dc4ee3c40391b",
"reference": "61af68dba333e2d376a325a29c2a3f2a605b4876", "reference": "7e2603bcc598e14804c4d2359d8dc4ee3c40391b",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=7.2.5", "php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
"symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-mbstring": "~1.0",
"symfony/polyfill-php80": "^1.15", "symfony/polyfill-php80": "^1.15",
"symfony/translation-contracts": "^2.3" "symfony/translation-contracts": "^2.3"
@ -1256,6 +1327,7 @@
"symfony/finder": "^4.4|^5.0", "symfony/finder": "^4.4|^5.0",
"symfony/http-kernel": "^5.0", "symfony/http-kernel": "^5.0",
"symfony/intl": "^4.4|^5.0", "symfony/intl": "^4.4|^5.0",
"symfony/polyfill-intl-icu": "^1.21",
"symfony/service-contracts": "^1.1.2|^2", "symfony/service-contracts": "^1.1.2|^2",
"symfony/yaml": "^4.4|^5.0" "symfony/yaml": "^4.4|^5.0"
}, },
@ -1264,7 +1336,7 @@
"symfony/config": "", "symfony/config": "",
"symfony/yaml": "" "symfony/yaml": ""
}, },
"time": "2021-05-16T13:07:46+00:00", "time": "2021-06-06T09:51:56+00:00",
"type": "library", "type": "library",
"installation-source": "dist", "installation-source": "dist",
"autoload": { "autoload": {
@ -1295,7 +1367,7 @@
"description": "Provides tools to internationalize your application", "description": "Provides tools to internationalize your application",
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"support": { "support": {
"source": "https://github.com/symfony/translation/tree/v5.2.9" "source": "https://github.com/symfony/translation/tree/v5.3.2"
}, },
"funding": [ "funding": [
{ {
@ -1396,17 +1468,17 @@
}, },
{ {
"name": "symfony/var-dumper", "name": "symfony/var-dumper",
"version": "v5.2.8", "version": "v5.3.2",
"version_normalized": "5.2.8.0", "version_normalized": "5.3.2.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/symfony/var-dumper.git", "url": "https://github.com/symfony/var-dumper.git",
"reference": "d693200a73fae179d27f8f1b16b4faf3e8569eba" "reference": "905a22c68b292ffb6f20d7636c36b220d1fba5ae"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/symfony/var-dumper/zipball/d693200a73fae179d27f8f1b16b4faf3e8569eba", "url": "https://api.github.com/repos/symfony/var-dumper/zipball/905a22c68b292ffb6f20d7636c36b220d1fba5ae",
"reference": "d693200a73fae179d27f8f1b16b4faf3e8569eba", "reference": "905a22c68b292ffb6f20d7636c36b220d1fba5ae",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1429,7 +1501,7 @@
"ext-intl": "To show region name in time zone dump", "ext-intl": "To show region name in time zone dump",
"symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
}, },
"time": "2021-05-07T13:42:21+00:00", "time": "2021-06-06T09:51:56+00:00",
"bin": [ "bin": [
"Resources/bin/var-dump-server" "Resources/bin/var-dump-server"
], ],
@ -1467,7 +1539,7 @@
"dump" "dump"
], ],
"support": { "support": {
"source": "https://github.com/symfony/var-dumper/tree/v5.2.8" "source": "https://github.com/symfony/var-dumper/tree/v5.3.2"
}, },
"funding": [ "funding": [
{ {

View File

@ -40,12 +40,12 @@
), ),
'directorytree/ldaprecord' => 'directorytree/ldaprecord' =>
array ( array (
'pretty_version' => 'v2.4.6', 'pretty_version' => 'v2.5.0',
'version' => '2.4.6.0', 'version' => '2.5.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '824a49feae4da52a522b3ec60ecad508b8f4ed23', 'reference' => 'ff7a92615fdc3f8b7f3d347c2847ce7ce06db287',
), ),
'exorus/php-mime-mail-parser' => 'exorus/php-mime-mail-parser' =>
array ( array (
@ -56,12 +56,12 @@
), ),
'illuminate/contracts' => 'illuminate/contracts' =>
array ( array (
'pretty_version' => 'v8.42.1', 'pretty_version' => 'v8.48.0',
'version' => '8.42.1.0', 'version' => '8.48.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '68036b4fb17ad40a599323bda3f2c0845c8100d8', 'reference' => '199fcedc161ba4a0b83feaddc4629f395dbf1641',
), ),
'matthiasmullie/minify' => 'matthiasmullie/minify' =>
array ( array (
@ -99,12 +99,12 @@
), ),
'nesbot/carbon' => 'nesbot/carbon' =>
array ( array (
'pretty_version' => '2.48.0', 'pretty_version' => '2.49.0',
'version' => '2.48.0.0', 'version' => '2.49.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'd3c447f21072766cddec3522f9468a5849a76147', 'reference' => '93d9db91c0235c486875d22f1e08b50bdf3e6eee',
), ),
'paragonie/random_compat' => 'paragonie/random_compat' =>
array ( array (
@ -126,12 +126,12 @@
), ),
'phpmailer/phpmailer' => 'phpmailer/phpmailer' =>
array ( array (
'pretty_version' => 'v6.4.1', 'pretty_version' => 'v6.5.0',
'version' => '6.4.1.0', 'version' => '6.5.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '9256f12d8fb0cd0500f93b19e18c356906cbed3d', 'reference' => 'a5b5c43e50b7fba655f793ad27303cd74c57363c',
), ),
'psr/container' => 'psr/container' =>
array ( array (
@ -178,32 +178,41 @@
), ),
'reference' => 'cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad', 'reference' => 'cdb89f6ffa2c4cc78f8ed9ea6ee0594a9133ccad',
), ),
'symfony/polyfill-mbstring' => 'symfony/deprecation-contracts' =>
array ( array (
'pretty_version' => 'v1.22.1', 'pretty_version' => 'v2.4.0',
'version' => '1.22.1.0', 'version' => '2.4.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '5232de97ee3b75b0360528dae24e73db49566ab1', 'reference' => '5f38c8804a9e97d23e0c8d63341088cd8a22d627',
),
'symfony/polyfill-mbstring' =>
array (
'pretty_version' => 'v1.23.0',
'version' => '1.23.0.0',
'aliases' =>
array (
),
'reference' => '2df51500adbaebdc4c38dea4c89a2e131c45c8a1',
), ),
'symfony/polyfill-php80' => 'symfony/polyfill-php80' =>
array ( array (
'pretty_version' => 'v1.22.1', 'pretty_version' => 'v1.23.0',
'version' => '1.22.1.0', 'version' => '1.23.0.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'dc3063ba22c2a1fd2f45ed856374d79114998f91', 'reference' => 'eca0bf41ed421bed1b57c4958bab16aa86b757d0',
), ),
'symfony/translation' => 'symfony/translation' =>
array ( array (
'pretty_version' => 'v5.2.9', 'pretty_version' => 'v5.3.2',
'version' => '5.2.9.0', 'version' => '5.3.2.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => '61af68dba333e2d376a325a29c2a3f2a605b4876', 'reference' => '7e2603bcc598e14804c4d2359d8dc4ee3c40391b',
), ),
'symfony/translation-contracts' => 'symfony/translation-contracts' =>
array ( array (
@ -223,12 +232,12 @@
), ),
'symfony/var-dumper' => 'symfony/var-dumper' =>
array ( array (
'pretty_version' => 'v5.2.8', 'pretty_version' => 'v5.3.2',
'version' => '5.2.8.0', 'version' => '5.3.2.0',
'aliases' => 'aliases' =>
array ( array (
), ),
'reference' => 'd693200a73fae179d27f8f1b16b4faf3e8569eba', 'reference' => '905a22c68b292ffb6f20d7636c36b220d1fba5ae',
), ),
'tightenco/collect' => 'tightenco/collect' =>
array ( array (

View File

@ -1,33 +0,0 @@
name: fix-style
on:
push:
pull_request:
paths:
- '**.php'
jobs:
php-cs-fixer:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v2
with:
ref: ${{ github.head_ref }}
- name: Setup PHP
uses: shivammathur/setup-php@v1
with:
php-version: '7.4'
extensions: mbstring, intl, gd, xml, dom, json, fileinfo, curl, zip, iconv
- name: Install Dependencies
run: composer install --prefer-dist
- name: Fix Style
run: ./vendor/bin/php-cs-fixer fix --diff --allow-risky=yes
- name: Commit Changes
uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: Fix styling changes

View File

@ -4,7 +4,7 @@ on:
push: push:
pull_request: pull_request:
schedule: schedule:
- cron: '0 0 * * *' - cron: "0 0 * * *"
jobs: jobs:
run-tests: run-tests:
@ -12,7 +12,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
php: [8.0, 7.4, 7.3, 7.2] php: [8.0, 7.4, 7.3]
name: P${{ matrix.php }} name: P${{ matrix.php }}

View File

@ -1,141 +0,0 @@
<?php
$finder = (new Symfony\Component\Finder\Finder)
->in([
__DIR__.'/src',
__DIR__.'/tests',
])
->name('*.php')
->ignoreVCS(true)
->ignoreDotFiles(true);
return (new PhpCsFixer\Config)
->setRules([
'array_syntax' => ['syntax' => 'short'],
'binary_operator_spaces' => [
'default' => 'single_space',
'operators' => ['=>' => null],
],
'blank_line_after_namespace' => true,
'blank_line_after_opening_tag' => true,
'blank_line_before_statement' => [
'statements' => ['return'],
],
'braces' => true,
'cast_spaces' => true,
'class_attributes_separation' => [
'elements' => ['method' => 'one'],
],
'class_definition' => true,
'concat_space' => [
'spacing' => 'none',
],
'constant_case' => true,
'declare_equal_normalize' => true,
'elseif' => true,
'encoding' => true,
'full_opening_tag' => true,
'fully_qualified_strict_types' => true,
'function_declaration' => true,
'function_typehint_space' => true,
'general_phpdoc_tag_rename' => true,
'heredoc_to_nowdoc' => true,
'include' => true,
'increment_style' => ['style' => 'post'],
'indentation_type' => true,
'linebreak_after_opening_tag' => true,
'line_ending' => true,
'lowercase_cast' => true,
'lowercase_keywords' => true,
'lowercase_static_reference' => true,
'magic_method_casing' => true,
'magic_constant_casing' => true,
'method_argument_space' => true,
'native_function_casing' => true,
'no_alias_functions' => true,
'no_extra_blank_lines' => [
'tokens' => [
'extra',
'throw',
'use',
'use_trait',
],
],
'no_blank_lines_after_class_opening' => true,
'no_blank_lines_after_phpdoc' => true,
'no_closing_tag' => true,
'no_empty_phpdoc' => true,
'no_empty_statement' => true,
'no_leading_import_slash' => true,
'no_leading_namespace_whitespace' => true,
'no_mixed_echo_print' => [
'use' => 'echo',
],
'no_multiline_whitespace_around_double_arrow' => true,
'multiline_whitespace_before_semicolons' => [
'strategy' => 'no_multi_line',
],
'no_short_bool_cast' => true,
'no_singleline_whitespace_before_semicolons' => true,
'no_spaces_after_function_name' => true,
'no_spaces_around_offset' => true,
'no_spaces_inside_parenthesis' => true,
'no_trailing_comma_in_list_call' => true,
'no_trailing_comma_in_singleline_array' => true,
'no_trailing_whitespace' => true,
'no_trailing_whitespace_in_comment' => true,
'no_unneeded_control_parentheses' => true,
'no_unreachable_default_argument_value' => true,
'no_useless_return' => true,
'no_unused_imports' => true,
'no_whitespace_before_comma_in_array' => true,
'no_whitespace_in_blank_line' => true,
'normalize_index_brace' => true,
'not_operator_with_successor_space' => true,
'object_operator_without_whitespace' => true,
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'phpdoc_align' => true,
'phpdoc_indent' => true,
'phpdoc_inline_tag_normalizer' => true,
'phpdoc_no_access' => true,
'phpdoc_no_package' => true,
'phpdoc_no_useless_inheritdoc' => true,
'phpdoc_scalar' => true,
'phpdoc_single_line_var_spacing' => true,
'phpdoc_summary' => true,
'phpdoc_to_comment' => true,
'phpdoc_tag_type' => true,
'phpdoc_trim' => true,
'phpdoc_types' => true,
'phpdoc_var_without_name' => true,
'php_unit_method_casing' => [
'case' => 'snake_case',
],
'psr_autoloading' => true,
'self_accessor' => true,
'short_scalar_cast' => true,
'simplified_null_return' => false,
'single_blank_line_at_eof' => true,
'single_blank_line_before_namespace' => true,
'single_class_element_per_statement' => true,
'single_import_per_statement' => true,
'single_line_after_imports' => true,
'single_line_comment_style' => [
'comment_types' => ['hash'],
],
'single_quote' => true,
'space_after_semicolon' => true,
'standardize_not_equals' => true,
'switch_case_semicolon_to_colon' => true,
'switch_case_space' => true,
'ternary_operator_spaces' => true,
'trailing_comma_in_multiline' => [
'elements' => ['arrays'],
],
'trim_array_spaces' => true,
'unary_operator_spaces' => true,
'visibility_required' => [
'elements' => ['method', 'property'],
],
'whitespace_after_comma_in_array' => true,
])->setFinder($finder);

View File

@ -0,0 +1,4 @@
preset: laravel
enabled:
- phpdoc_align
- unalign_double_arrow

View File

@ -1,4 +0,0 @@
{
"php-cs-fixer.onsave": true,
"php-cs-fixer.allowRisky": true,
}

View File

@ -29,7 +29,7 @@
} }
], ],
"require": { "require": {
"php": ">=7.2", "php": ">=7.3",
"ext-ldap": "*", "ext-ldap": "*",
"ext-json": "*", "ext-json": "*",
"psr/log": "^1.0", "psr/log": "^1.0",
@ -41,7 +41,7 @@
"require-dev": { "require-dev": {
"phpunit/phpunit": "^8.0", "phpunit/phpunit": "^8.0",
"mockery/mockery": "^1.0", "mockery/mockery": "^1.0",
"friendsofphp/php-cs-fixer": "^3.0" "spatie/ray": "^1.24"
}, },
"archive": { "archive": {
"exclude": ["/tests"] "exclude": ["/tests"]

View File

@ -54,10 +54,10 @@ class Guard
* @param string $password * @param string $password
* @param bool $stayBound * @param bool $stayBound
* *
* @return bool
*
* @throws UsernameRequiredException * @throws UsernameRequiredException
* @throws PasswordRequiredException * @throws PasswordRequiredException
*
* @return bool
*/ */
public function attempt($username, $password, $stayBound = false) public function attempt($username, $password, $stayBound = false)
{ {

View File

@ -124,9 +124,9 @@ class DomainConfiguration
* *
* @param string $key * @param string $key
* *
* @return mixed
*
* @throws ConfigurationException When the option specified does not exist. * @throws ConfigurationException When the option specified does not exist.
*
* @return mixed
*/ */
public function get($key) public function get($key)
{ {
@ -155,9 +155,9 @@ class DomainConfiguration
* @param string $key * @param string $key
* @param mixed $value * @param mixed $value
* *
* @return bool
*
* @throws ConfigurationException When an option value given is an invalid type. * @throws ConfigurationException When an option value given is an invalid type.
*
* @return bool
*/ */
protected function validate($key, $value) protected function validate($key, $value)
{ {

View File

@ -33,9 +33,9 @@ abstract class Validator
/** /**
* Validates the configuration value. * Validates the configuration value.
* *
* @return bool
*
* @throws \LdapRecord\Configuration\ConfigurationException When the value given fails validation. * @throws \LdapRecord\Configuration\ConfigurationException When the value given fails validation.
*
* @return bool
*/ */
abstract public function validate(); abstract public function validate();
} }

View File

@ -111,9 +111,9 @@ class Connection
* *
* @param array $config * @param array $config
* *
* @return $this
*
* @throws Configuration\ConfigurationException * @throws Configuration\ConfigurationException
*
* @return $this
*/ */
public function setConfiguration($config = []) public function setConfiguration($config = [])
{ {
@ -241,10 +241,10 @@ class Connection
* @param string|null $username * @param string|null $username
* @param string|null $password * @param string|null $password
* *
* @return Connection
*
* @throws Auth\BindException * @throws Auth\BindException
* @throws LdapRecordException * @throws LdapRecordException
*
* @return Connection
*/ */
public function connect($username = null, $password = null) public function connect($username = null, $password = null)
{ {
@ -274,10 +274,10 @@ class Connection
/** /**
* Reconnect to the LDAP server. * Reconnect to the LDAP server.
* *
* @return void
*
* @throws Auth\BindException * @throws Auth\BindException
* @throws ConnectionException * @throws ConnectionException
*
* @return void
*/ */
public function reconnect() public function reconnect()
{ {
@ -385,9 +385,9 @@ class Connection
* *
* @param Closure $operation * @param Closure $operation
* *
* @return mixed
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return mixed
*/ */
protected function runOperationCallback(Closure $operation) protected function runOperationCallback(Closure $operation)
{ {
@ -442,9 +442,9 @@ class Connection
* @param LdapRecordException $e * @param LdapRecordException $e
* @param Closure $operation * @param Closure $operation
* *
* @return mixed
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return mixed
*/ */
protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation) protected function tryAgainIfCausedByLostConnection(LdapRecordException $e, Closure $operation)
{ {
@ -463,9 +463,9 @@ class Connection
* *
* @param Closure $operation * @param Closure $operation
* *
* @return mixed
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return mixed
*/ */
protected function retry(Closure $operation) protected function retry(Closure $operation)
{ {
@ -486,9 +486,9 @@ class Connection
* @param LdapRecordException $e * @param LdapRecordException $e
* @param Closure $operation * @param Closure $operation
* *
* @return mixed
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return mixed
*/ */
protected function retryOnNextHost(LdapRecordException $e, Closure $operation) protected function retryOnNextHost(LdapRecordException $e, Closure $operation)
{ {

View File

@ -84,7 +84,7 @@ class Container
*/ */
public static function getNewInstance() public static function getNewInstance()
{ {
return static::setInstance(new static); return static::setInstance(new static());
} }
/** /**
@ -117,9 +117,9 @@ class Container
* *
* @param string|null $name * @param string|null $name
* *
* @return Connection
*
* @throws ContainerException If the given connection does not exist. * @throws ContainerException If the given connection does not exist.
*
* @return Connection
*/ */
public static function getConnection($name = null) public static function getConnection($name = null)
{ {
@ -332,9 +332,9 @@ class Container
* *
* @param string|null $name * @param string|null $name
* *
* @return Connection
*
* @throws ContainerException If the given connection does not exist. * @throws ContainerException If the given connection does not exist.
*
* @return Connection
*/ */
public function get($name = null) public function get($name = null)
{ {

View File

@ -2,7 +2,7 @@
namespace LdapRecord\Events; namespace LdapRecord\Events;
use Tightenco\Collect\Support\Arr; use LdapRecord\Support\Arr;
/** /**
* Class Dispatcher. * Class Dispatcher.
@ -101,7 +101,7 @@ class Dispatcher implements DispatcherInterface
// When the given "event" is actually an object we will assume it is an event // When the given "event" is actually an object we will assume it is an event
// object and use the class as the event name and this event itself as the // object and use the class as the event name and this event itself as the
// payload to the handler, which makes object based events quite simple. // payload to the handler, which makes object based events quite simple.
list($event, $payload) = $this->parseEventAndPayload( [$event, $payload] = $this->parseEventAndPayload(
$event, $event,
$payload $payload
); );
@ -142,7 +142,7 @@ class Dispatcher implements DispatcherInterface
protected function parseEventAndPayload($event, $payload) protected function parseEventAndPayload($event, $payload)
{ {
if (is_object($event)) { if (is_object($event)) {
list($payload, $event) = [[$event], get_class($event)]; [$payload, $event] = [[$event], get_class($event)];
} }
return [$event, Arr::wrap($payload)]; return [$event, Arr::wrap($payload)];

View File

@ -119,7 +119,7 @@ class Logger
$message = "LDAP ({$connection->getHost()})" $message = "LDAP ({$connection->getHost()})"
." - Operation: {$this->getOperationName($event)}" ." - Operation: {$this->getOperationName($event)}"
." - Base DN: {$query->getDn()}" ." - Base DN: {$query->getDn()}"
." - Filter: {$query->getUnescapedQuery()}" ." - Filter: {$query->getQuery()}"
." - Selected: ({$selected})" ." - Selected: ({$selected})"
." - Time Elapsed: {$event->getTime()}"; ." - Time Elapsed: {$event->getTime()}";

View File

@ -188,7 +188,7 @@ class Ldap extends LdapBase
{ {
$this->bound = false; $this->bound = false;
$this->host = $this->getConnectionString($hosts, $port); $this->host = $this->makeConnectionUris($hosts, $port);
return $this->connection = $this->executeFailableOperation(function () { return $this->connection = $this->executeFailableOperation(function () {
return ldap_connect($this->host); return ldap_connect($this->host);

View File

@ -152,12 +152,15 @@ abstract class LdapBase implements LdapInterface
* *
* @param Closure $operation * @param Closure $operation
* *
* @return mixed
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return mixed
*/ */
protected function executeFailableOperation(Closure $operation) protected function executeFailableOperation(Closure $operation)
{ {
// If some older versions of PHP, errors are reported instead of throwing
// exceptions, which could be a signifcant detriment to our application.
// Here, we will enforce these operations to throw exceptions instead.
set_error_handler(function ($severity, $message, $file, $line) { set_error_handler(function ($severity, $message, $file, $line) {
if (! $this->shouldBypassError($message)) { if (! $this->shouldBypassError($message)) {
throw new ErrorException($message, $severity, $severity, $file, $line); throw new ErrorException($message, $severity, $severity, $file, $line);
@ -169,6 +172,9 @@ abstract class LdapBase implements LdapInterface
return $result; return $result;
} }
// If the failed query operation was a based on a query being executed
// -- such as a search, read, or listing, then we can safely return
// the failed response here and prevent throwning an exception.
if ($this->shouldBypassFailure($method = debug_backtrace()[1]['function'])) { if ($this->shouldBypassFailure($method = debug_backtrace()[1]['function'])) {
return $result; return $result;
} }
@ -208,6 +214,8 @@ abstract class LdapBase implements LdapInterface
/** /**
* Determine if the current PHP version supports server controls. * Determine if the current PHP version supports server controls.
* *
* @deprecated
*
* @return bool * @return bool
*/ */
public function supportsServerControlsInMethods() public function supportsServerControlsInMethods()
@ -223,18 +231,33 @@ abstract class LdapBase implements LdapInterface
* *
* @return string * @return string
*/ */
protected function getConnectionString($hosts, $port) protected function makeConnectionUris($hosts, $port)
{ {
// If we are using SSL and using the default port, we // If an attempt to connect via SSL protocol is being performed,
// will override it to use the default SSL port. // and we are still using the default port, we will swap it
// for the default SSL port, for developer convenience.
if ($this->isUsingSSL() && $port == static::PORT) { if ($this->isUsingSSL() && $port == static::PORT) {
$port = static::PORT_SSL; $port = static::PORT_SSL;
} }
$hosts = array_map(function ($host) use ($port) { // The blank space here is intentional. PHP's LDAP extension
// requires additional hosts to be seperated by a blank
// space, so that it can parse each individually.
return implode(' ', $this->assembleHostUris($hosts, $port));
}
/**
* Assemble the host URI strings.
*
* @param array|string $hosts
* @param string $port
*
* @return array
*/
protected function assembleHostUris($hosts, $port)
{
return array_map(function ($host) use ($port) {
return "{$this->getProtocol()}{$host}:{$port}"; return "{$this->getProtocol()}{$host}:{$port}";
}, (array) $hosts); }, (array) $hosts);
return implode(' ', $hosts);
} }
} }

View File

@ -202,9 +202,9 @@ interface LdapInterface
* *
* @link http://php.net/manual/en/function.ldap-start-tls.php * @link http://php.net/manual/en/function.ldap-start-tls.php
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function startTLS(); public function startTLS();
@ -310,9 +310,9 @@ interface LdapInterface
* @param string $username * @param string $username
* @param string $password * @param string $password
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function bind($username, $password); public function bind($username, $password);
@ -324,9 +324,9 @@ interface LdapInterface
* @param string $dn * @param string $dn
* @param array $entry * @param array $entry
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function add($dn, array $entry); public function add($dn, array $entry);
@ -337,9 +337,9 @@ interface LdapInterface
* *
* @param string $dn * @param string $dn
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function delete($dn); public function delete($dn);
@ -353,9 +353,9 @@ interface LdapInterface
* @param string $newParent * @param string $newParent
* @param bool $deleteOldRdn * @param bool $deleteOldRdn
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false); public function rename($dn, $newRdn, $newParent, $deleteOldRdn = false);
@ -367,9 +367,9 @@ interface LdapInterface
* @param string $dn * @param string $dn
* @param array $entry * @param array $entry
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function modify($dn, array $entry); public function modify($dn, array $entry);
@ -381,9 +381,9 @@ interface LdapInterface
* @param string $dn * @param string $dn
* @param array $values * @param array $values
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function modifyBatch($dn, array $values); public function modifyBatch($dn, array $values);
@ -395,9 +395,9 @@ interface LdapInterface
* @param string $dn * @param string $dn
* @param array $entry * @param array $entry
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function modAdd($dn, array $entry); public function modAdd($dn, array $entry);
@ -409,9 +409,9 @@ interface LdapInterface
* @param string $dn * @param string $dn
* @param array $entry * @param array $entry
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function modReplace($dn, array $entry); public function modReplace($dn, array $entry);
@ -423,9 +423,9 @@ interface LdapInterface
* @param string $dn * @param string $dn
* @param array $entry * @param array $entry
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function modDelete($dn, array $entry); public function modDelete($dn, array $entry);

View File

@ -86,9 +86,9 @@ class Entry extends BaseEntry implements ActiveDirectory
* *
* @param string|null $newParentDn * @param string|null $newParentDn
* *
* @return bool
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return bool
*/ */
public function restore($newParentDn = null) public function restore($newParentDn = null)
{ {
@ -120,13 +120,13 @@ class Entry extends BaseEntry implements ActiveDirectory
* *
* @param string|null $connection * @param string|null $connection
* *
* @return static
*
* @throws \LdapRecord\Models\ModelNotFoundException * @throws \LdapRecord\Models\ModelNotFoundException
*
* @return static
*/ */
public static function getRootDse($connection = null) public static function getRootDse($connection = null)
{ {
return static::on($connection ?? (new static)->getConnectionName()) return static::on($connection ?? (new static())->getConnectionName())
->in(null) ->in(null)
->read() ->read()
->whereHas('objectclass') ->whereHas('objectclass')

View File

@ -16,6 +16,6 @@ class ExchangeDatabase extends Entry
{ {
parent::boot(); parent::boot();
static::addGlobalScope(new Scopes\InConfigurationContext); static::addGlobalScope(new Scopes\InConfigurationContext());
} }
} }

View File

@ -16,7 +16,7 @@ class ExchangeServer extends Entry
{ {
parent::boot(); parent::boot();
static::addGlobalScope(new Scopes\HasServerRoleAttribute); static::addGlobalScope(new Scopes\HasServerRoleAttribute());
static::addGlobalScope(new Scopes\InConfigurationContext); static::addGlobalScope(new Scopes\InConfigurationContext());
} }
} }

View File

@ -15,9 +15,9 @@ class InConfigurationContext implements Scope
* @param Builder $query * @param Builder $query
* @param Model $model * @param Model $model
* *
* @return void
*
* @throws \LdapRecord\Models\ModelNotFoundException * @throws \LdapRecord\Models\ModelNotFoundException
*
* @return void
*/ */
public function apply(Builder $query, Model $model) public function apply(Builder $query, Model $model)
{ {
@ -29,9 +29,9 @@ class InConfigurationContext implements Scope
* *
* @param Model $model * @param Model $model
* *
* @return mixed
*
* @throws \LdapRecord\Models\ModelNotFoundException * @throws \LdapRecord\Models\ModelNotFoundException
*
* @return mixed
*/ */
protected function getConfigurationNamingContext(Model $model) protected function getConfigurationNamingContext(Model $model)
{ {

View File

@ -3,6 +3,7 @@
namespace LdapRecord\Models\Attributes; namespace LdapRecord\Models\Attributes;
use LdapRecord\EscapesValues; use LdapRecord\EscapesValues;
use LdapRecord\Support\Arr;
class DistinguishedNameBuilder class DistinguishedNameBuilder
{ {
@ -107,7 +108,7 @@ class DistinguishedNameBuilder
// RDN's have been given if the value is null, and // RDN's have been given if the value is null, and
// attempt to break them into their components. // attempt to break them into their components.
if (is_null($value)) { if (is_null($value)) {
$attributes = is_array($attribute) ? $attribute : [$attribute]; $attributes = Arr::wrap($attribute);
$components = array_map([$this, 'makeComponentizedArray'], $attributes); $components = array_map([$this, 'makeComponentizedArray'], $attributes);
} else { } else {

View File

@ -244,9 +244,9 @@ class Password
* *
* @param int $type * @param int $type
* *
* @return array
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*
* @return array
*/ */
protected static function makeCryptPrefixAndLength($type) protected static function makeCryptPrefixAndLength($type)
{ {
@ -297,9 +297,9 @@ class Password
/** /**
* Attempt to retrieve a salt from the encrypted password. * Attempt to retrieve a salt from the encrypted password.
* *
* @return string
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return string
*/ */
public static function getSalt($encryptedPassword) public static function getSalt($encryptedPassword)
{ {
@ -321,9 +321,9 @@ class Password
* *
* @param string $method * @param string $method
* *
* @return bool
*
* @throws \ReflectionException * @throws \ReflectionException
*
* @return bool
*/ */
public static function hashMethodRequiresSalt($method): bool public static function hashMethodRequiresSalt($method): bool
{ {

View File

@ -61,9 +61,9 @@ class Timestamp
* *
* @param mixed $value * @param mixed $value
* *
* @return float|string
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return float|string
*/ */
public function fromDateTime($value) public function fromDateTime($value)
{ {
@ -121,9 +121,9 @@ class Timestamp
* *
* @param mixed $value * @param mixed $value
* *
* @return Carbon|false
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return Carbon|false
*/ */
public function toDateTime($value) public function toDateTime($value)
{ {
@ -213,9 +213,9 @@ class Timestamp
* *
* @param int $value * @param int $value
* *
* @return DateTime|bool
*
* @throws \Exception * @throws \Exception
*
* @return DateTime|bool
*/ */
protected function convertWindowsIntegerTimeToDateTime($value) protected function convertWindowsIntegerTimeToDateTime($value)
{ {

View File

@ -5,7 +5,7 @@ namespace LdapRecord\Models;
use Closure; use Closure;
use LdapRecord\Models\Attributes\DistinguishedName; use LdapRecord\Models\Attributes\DistinguishedName;
use LdapRecord\Query\Collection as QueryCollection; use LdapRecord\Query\Collection as QueryCollection;
use Tightenco\Collect\Support\Arr; use LdapRecord\Support\Arr;
class Collection extends QueryCollection class Collection extends QueryCollection
{ {

View File

@ -9,7 +9,7 @@ use LdapRecord\LdapRecordException;
use LdapRecord\Models\Attributes\MbString; use LdapRecord\Models\Attributes\MbString;
use LdapRecord\Models\Attributes\Timestamp; use LdapRecord\Models\Attributes\Timestamp;
use LdapRecord\Models\DetectsResetIntegers; use LdapRecord\Models\DetectsResetIntegers;
use Tightenco\Collect\Support\Arr; use LdapRecord\Support\Arr;
trait HasAttributes trait HasAttributes
{ {
@ -190,7 +190,7 @@ trait HasAttributes
// We want to spin through all the mutated attributes for this model and call // We want to spin through all the mutated attributes for this model and call
// the mutator for the attribute. We cache off every mutated attributes so // the mutator for the attribute. We cache off every mutated attributes so
// we don't have to constantly check on attributes that actually change. // we don't have to constantly check on attributes that actually change.
if (! array_key_exists($key, $attributes)) { if (! Arr::exists($attributes, $key)) {
continue; continue;
} }
@ -311,9 +311,9 @@ trait HasAttributes
* @param string $type * @param string $type
* @param mixed $value * @param mixed $value
* *
* @return float|string
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return float|string
*/ */
public function fromDateTime($type, $value) public function fromDateTime($type, $value)
{ {
@ -326,9 +326,9 @@ trait HasAttributes
* @param mixed $value * @param mixed $value
* @param string $type * @param string $type
* *
* @return Carbon|false
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return Carbon|false
*/ */
public function asDateTime($value, $type) public function asDateTime($value, $type)
{ {
@ -876,9 +876,9 @@ trait HasAttributes
// LDAP search results will contain the distinguished // LDAP search results will contain the distinguished
// name inside of the `dn` key. We will retrieve this, // name inside of the `dn` key. We will retrieve this,
// and then set it on the model for accessibility. // and then set it on the model for accessibility.
if (array_key_exists('dn', $attributes)) { if (Arr::exists($attributes, 'dn')) {
$this->dn = is_array($attributes['dn']) $this->dn = Arr::accessible($attributes['dn'])
? reset($attributes['dn']) ? Arr::first($attributes['dn'])
: $attributes['dn']; : $attributes['dn'];
} }

View File

@ -14,9 +14,9 @@ trait HasGlobalScopes
* @param Scope|Closure|string $scope * @param Scope|Closure|string $scope
* @param Closure|null $implementation * @param Closure|null $implementation
* *
* @return mixed
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*
* @return mixed
*/ */
public static function addGlobalScope($scope, Closure $implementation = null) public static function addGlobalScope($scope, Closure $implementation = null)
{ {

View File

@ -159,9 +159,9 @@ trait HasPassword
* @param string $password * @param string $password
* @param string $salt * @param string $salt
* *
* @return string
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return string
*/ */
protected function getHashedPassword($method, $password, $salt = null) protected function getHashedPassword($method, $password, $salt = null)
{ {
@ -179,9 +179,9 @@ trait HasPassword
/** /**
* Validates that the current LDAP connection is secure. * Validates that the current LDAP connection is secure.
* *
* @return void
*
* @throws ConnectionException * @throws ConnectionException
*
* @return void
*/ */
protected function validateSecureConnection() protected function validateSecureConnection()
{ {

View File

@ -5,7 +5,7 @@ namespace LdapRecord\Models\Concerns;
use LdapRecord\Models\Relations\HasMany; use LdapRecord\Models\Relations\HasMany;
use LdapRecord\Models\Relations\HasManyIn; use LdapRecord\Models\Relations\HasManyIn;
use LdapRecord\Models\Relations\HasOne; use LdapRecord\Models\Relations\HasOne;
use Tightenco\Collect\Support\Arr; use LdapRecord\Support\Arr;
trait HasRelationships trait HasRelationships
{ {

View File

@ -13,6 +13,7 @@ use LdapRecord\Models\Attributes\Guid;
use LdapRecord\Models\Events\Renamed; use LdapRecord\Models\Events\Renamed;
use LdapRecord\Models\Events\Renaming; use LdapRecord\Models\Events\Renaming;
use LdapRecord\Query\Model\Builder; use LdapRecord\Query\Model\Builder;
use LdapRecord\Support\Arr;
use UnexpectedValueException; use UnexpectedValueException;
/** @mixin Builder */ /** @mixin Builder */
@ -675,7 +676,7 @@ abstract class Model implements ArrayAccess, JsonSerializable
} }
/** /**
* Get the models batch modifications to be processed. * Get the model's batch modifications to be processed.
* *
* @return array * @return array
*/ */
@ -713,9 +714,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
* *
* @param array|BatchModification $mod * @param array|BatchModification $mod
* *
* @return $this
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*
* @return $this
*/ */
public function addModification($mod = []) public function addModification($mod = [])
{ {
@ -735,7 +736,7 @@ abstract class Model implements ArrayAccess, JsonSerializable
} }
/** /**
* Get the models guid attribute key name. * Get the model's guid attribute key name.
* *
* @return string * @return string
*/ */
@ -745,7 +746,7 @@ abstract class Model implements ArrayAccess, JsonSerializable
} }
/** /**
* Get the models ANR attributes for querying when incompatible with ANR. * Get the model's ANR attributes for querying when incompatible with ANR.
* *
* @return array * @return array
*/ */
@ -803,7 +804,7 @@ abstract class Model implements ArrayAccess, JsonSerializable
} }
/** /**
* Get the models binary object GUID. * Get the model's binary object GUID.
* *
* @link https://msdn.microsoft.com/en-us/library/ms679021(v=vs.85).aspx * @link https://msdn.microsoft.com/en-us/library/ms679021(v=vs.85).aspx
* *
@ -815,7 +816,17 @@ abstract class Model implements ArrayAccess, JsonSerializable
} }
/** /**
* Get the models string GUID. * Get the model's object classes.
*
* @return array
*/
public function getObjectClasses()
{
return $this->getAttribute('objectclass') ?: [];
}
/**
* Get the model's string GUID.
* *
* @return string|null * @return string|null
*/ */
@ -914,9 +925,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
* *
* @param array $attributes The attributes to update or create for the current entry. * @param array $attributes The attributes to update or create for the current entry.
* *
* @return void
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function save(array $attributes = []) public function save(array $attributes = [])
{ {
@ -934,9 +945,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
/** /**
* Inserts the model into the directory. * Inserts the model into the directory.
* *
* @return void
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
protected function performInsert() protected function performInsert()
{ {
@ -975,9 +986,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
/** /**
* Updates the model in the directory. * Updates the model in the directory.
* *
* @return void
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
protected function performUpdate() protected function performUpdate()
{ {
@ -1020,10 +1031,10 @@ abstract class Model implements ArrayAccess, JsonSerializable
* @param string $attribute The attribute to create * @param string $attribute The attribute to create
* @param mixed $value The value of the new attribute * @param mixed $value The value of the new attribute
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function createAttribute($attribute, $value) public function createAttribute($attribute, $value)
{ {
@ -1039,10 +1050,10 @@ abstract class Model implements ArrayAccess, JsonSerializable
* *
* @param array $attributes The attributes to update for the current entry. * @param array $attributes The attributes to update for the current entry.
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function update(array $attributes = []) public function update(array $attributes = [])
{ {
@ -1057,10 +1068,10 @@ abstract class Model implements ArrayAccess, JsonSerializable
* @param string $attribute The attribute to modify * @param string $attribute The attribute to modify
* @param mixed $value The new value for the attribute * @param mixed $value The new value for the attribute
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function updateAttribute($attribute, $value) public function updateAttribute($attribute, $value)
{ {
@ -1077,9 +1088,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
* @param Collection|array|string $dns * @param Collection|array|string $dns
* @param bool $recursive * @param bool $recursive
* *
* @return int
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return int
*/ */
public static function destroy($dns, $recursive = false) public static function destroy($dns, $recursive = false)
{ {
@ -1110,10 +1121,10 @@ abstract class Model implements ArrayAccess, JsonSerializable
* *
* @param bool $recursive Whether to recursively delete leaf nodes (models that are children). * @param bool $recursive Whether to recursively delete leaf nodes (models that are children).
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function delete($recursive = false) public function delete($recursive = false)
{ {
@ -1138,9 +1149,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
/** /**
* Deletes leaf nodes that are attached to the model. * Deletes leaf nodes that are attached to the model.
* *
* @return Collection
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return Collection
*/ */
protected function deleteLeafNodes() protected function deleteLeafNodes()
{ {
@ -1160,38 +1171,36 @@ abstract class Model implements ArrayAccess, JsonSerializable
* *
* Delete specific values in attributes: * Delete specific values in attributes:
* *
* ["memberuid" => "username"] * ["memberuid" => "jdoe"]
* *
* Delete an entire attribute: * Delete an entire attribute:
* *
* ["memberuid" => []] * ["memberuid" => []]
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function deleteAttribute($attributes) public function deleteAttribute($attributes)
{ {
$this->validateExistence(); $this->validateExistence();
// If we have been given a string, we will assume we're $attributes = $this->makeDeletableAttributes($attributes);
// removing a single attribute. Otherwise, we will
// assume it's an array of attributes to remove.
$attributes = is_string($attributes) ? [$attributes => []] : $attributes;
$this->newQuery()->deleteAttributes($this->dn, $attributes); $this->newQuery()->deleteAttributes($this->dn, $attributes);
foreach ($attributes as $attribute => $value) { foreach ($attributes as $attribute => $value) {
// If the attribute value is empty, we will remove // If the attribute value is empty, we can assume the
// the attribute from the model and continue on. // attribute was completely deleted from the model.
// We will pull the attribute out and continue on.
if (empty($value)) { if (empty($value)) {
unset($this->attributes[$attribute]); unset($this->attributes[$attribute]);
} }
// Otherwise, only specific attribute values have been // Otherwise, only specific attribute values have been
// removed. We will determine which ones have been // removed. We will determine which ones have been
// removed and update the attributes value. // removed and update the attributes value.
else { elseif (Arr::exists($this->attributes, $attribute)) {
$this->attributes[$attribute] = array_values( $this->attributes[$attribute] = array_values(
array_diff($this->attributes[$attribute], (array) $value) array_diff($this->attributes[$attribute], (array) $value)
); );
@ -1201,6 +1210,26 @@ abstract class Model implements ArrayAccess, JsonSerializable
$this->syncOriginal(); $this->syncOriginal();
} }
/**
* Make a deletable attribute array.
*
* @param string|array $attributes
*
* @return array
*/
protected function makeDeletableAttributes($attributes)
{
$delete = [];
foreach (Arr::wrap($attributes) as $key => $value) {
is_int($key)
? $delete[$value] = []
: $delete[$key] = Arr::wrap($value);
}
return $delete;
}
/** /**
* Move the model into the given new parent. * Move the model into the given new parent.
* *
@ -1209,11 +1238,11 @@ abstract class Model implements ArrayAccess, JsonSerializable
* @param static|string $newParentDn The new parent of the current model. * @param static|string $newParentDn The new parent of the current model.
* @param bool $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved. * @param bool $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved.
* *
* @return void
*
* @throws UnexpectedValueException * @throws UnexpectedValueException
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function move($newParentDn, $deleteOldRdn = true) public function move($newParentDn, $deleteOldRdn = true)
{ {
@ -1233,10 +1262,10 @@ abstract class Model implements ArrayAccess, JsonSerializable
* @param static|string|null $newParentDn The models new parent distinguished name (if moving). Leave this null if you are only renaming. Example: "ou=MovedUsers,dc=acme,dc=org" * @param static|string|null $newParentDn The models new parent distinguished name (if moving). Leave this null if you are only renaming. Example: "ou=MovedUsers,dc=acme,dc=org"
* @param bool|true $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved. * @param bool|true $deleteOldRdn Whether to delete the old models relative distinguished name once renamed / moved.
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function rename($rdn, $newParentDn = null, $deleteOldRdn = true) public function rename($rdn, $newParentDn = null, $deleteOldRdn = true)
{ {
@ -1339,9 +1368,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
*/ */
protected function isValidModification($mod) protected function isValidModification($mod)
{ {
return is_array($mod) && return Arr::accessible($mod)
array_key_exists(BatchModification::KEY_MODTYPE, $mod) && && Arr::exists($mod, BatchModification::KEY_MODTYPE)
array_key_exists(BatchModification::KEY_ATTRIB, $mod); && Arr::exists($mod, BatchModification::KEY_ATTRIB);
} }
/** /**
@ -1356,7 +1385,7 @@ abstract class Model implements ArrayAccess, JsonSerializable
foreach ($this->getDirty() as $attribute => $values) { foreach ($this->getDirty() as $attribute => $values) {
$modification = $this->newBatchModification($attribute, null, (array) $values); $modification = $this->newBatchModification($attribute, null, (array) $values);
if (array_key_exists($attribute, $this->original)) { if (Arr::exists($this->original, $attribute)) {
// If the attribute we're modifying has an original value, we will // If the attribute we're modifying has an original value, we will
// give the BatchModification object its values to automatically // give the BatchModification object its values to automatically
// determine which type of LDAP operation we need to perform. // determine which type of LDAP operation we need to perform.
@ -1376,9 +1405,9 @@ abstract class Model implements ArrayAccess, JsonSerializable
/** /**
* Validates that the current model exists. * Validates that the current model exists.
* *
* @return void
*
* @throws ModelDoesNotExistException * @throws ModelDoesNotExistException
*
* @return void
*/ */
protected function validateExistence() protected function validateExistence()
{ {

View File

@ -268,9 +268,9 @@ class HasMany extends OneToMany
* *
* @param string $model * @param string $model
* *
* @return Model
*
* @throws ModelNotFoundException * @throws ModelNotFoundException
*
* @return Model
*/ */
protected function getForeignModelByValueOrFail($model) protected function getForeignModelByValueOrFail($model)
{ {
@ -293,9 +293,9 @@ class HasMany extends OneToMany
* @param string|array $bypass * @param string|array $bypass
* @param mixed $value * @param mixed $value
* *
* @return mixed
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return mixed
*/ */
protected function attemptFailableOperation($operation, $bypass, $value) protected function attemptFailableOperation($operation, $bypass, $value)
{ {

View File

@ -27,9 +27,9 @@ class HasOne extends Relation
* *
* @param Model|string $model * @param Model|string $model
* *
* @return Model|string
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return Model|string
*/ */
public function attach($model) public function attach($model)
{ {
@ -45,9 +45,9 @@ class HasOne extends Relation
/** /**
* Detach the related model from the parent. * Detach the related model from the parent.
* *
* @return void
*
* @throws \LdapRecord\LdapRecordException * @throws \LdapRecord\LdapRecordException
*
* @return void
*/ */
public function detach() public function detach()
{ {

View File

@ -343,13 +343,11 @@ abstract class Relation
*/ */
protected function determineModelFromRelated(Model $model, array $related) protected function determineModelFromRelated(Model $model, array $related)
{ {
$objectClasses = $model->getAttribute('objectclass') ?? [];
// We must normalize all the related models object class // We must normalize all the related models object class
// names to the same case so we are able to properly // names to the same case so we are able to properly
// determine the owning model from search results. // determine the owning model from search results.
return array_search( return array_search(
$this->normalizeObjectClasses($objectClasses), $this->normalizeObjectClasses($model->getObjectClasses()),
array_map([$this, 'normalizeObjectClasses'], $related) array_map([$this, 'normalizeObjectClasses'], $related)
); );
} }

View File

@ -14,10 +14,10 @@ use LdapRecord\LdapRecordException;
use LdapRecord\Models\Model; use LdapRecord\Models\Model;
use LdapRecord\Query\Events\QueryExecuted; use LdapRecord\Query\Events\QueryExecuted;
use LdapRecord\Query\Model\Builder as ModelBuilder; use LdapRecord\Query\Model\Builder as ModelBuilder;
use LdapRecord\Query\Pagination\DeprecatedPaginator; use LdapRecord\Query\Pagination\LazyPaginator;
use LdapRecord\Query\Pagination\Paginator; use LdapRecord\Query\Pagination\Paginator;
use LdapRecord\Support\Arr;
use LdapRecord\Utilities; use LdapRecord\Utilities;
use Tightenco\Collect\Support\Arr;
class Builder class Builder
{ {
@ -484,6 +484,60 @@ class Builder
return $this->process($pages); return $this->process($pages);
} }
/**
* Runs the paginate operation with the given filter.
*
* @param string $filter
* @param int $perPage
* @param bool $isCritical
*
* @return array
*/
protected function runPaginate($filter, $perPage, $isCritical)
{
return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) {
return (new Paginator($this, $filter, $perPage, $isCritical))->execute($ldap);
});
}
/**
* Chunk the results of a paginated LDAP query.
*
* @param int $pageSize
* @param Closure $callback
* @param bool $isCritical
*
* @return void
*/
public function chunk($pageSize, Closure $callback, $isCritical = false)
{
$start = microtime(true);
$query = $this->getQuery();
foreach ($this->runChunk($query, $pageSize, $isCritical) as $chunk) {
$callback($this->process($chunk));
}
$this->logQuery($this, 'chunk', $this->getElapsedTime($start));
}
/**
* Runs the chunk operation with the given filter.
*
* @param string $filter
* @param int $perPage
* @param bool $isCritical
*
* @return array
*/
protected function runChunk($filter, $perPage, $isCritical)
{
return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) {
return (new LazyPaginator($this, $filter, $perPage, $isCritical))->execute($ldap);
});
}
/** /**
* Processes and converts the given LDAP results into models. * Processes and converts the given LDAP results into models.
* *
@ -574,26 +628,6 @@ class Builder
}); });
} }
/**
* Runs the paginate operation with the given filter.
*
* @param string $filter
* @param int $perPage
* @param bool $isCritical
*
* @return array
*/
protected function runPaginate($filter, $perPage, $isCritical)
{
return $this->connection->run(function (LdapInterface $ldap) use ($filter, $perPage, $isCritical) {
$paginator = $ldap->supportsServerControlsInMethods()
? new Paginator($this, $filter, $perPage, $isCritical)
: new DeprecatedPaginator($this, $filter, $perPage, $isCritical);
return $paginator->execute($ldap);
});
}
/** /**
* Parses the given LDAP resource by retrieving its entries. * Parses the given LDAP resource by retrieving its entries.
* *
@ -660,9 +694,9 @@ class Builder
* *
* @param array|string $columns * @param array|string $columns
* *
* @return Model|static
*
* @throws ObjectNotFoundException * @throws ObjectNotFoundException
*
* @return Model|static
*/ */
public function firstOrFail($columns = ['*']) public function firstOrFail($columns = ['*'])
{ {
@ -713,9 +747,9 @@ class Builder
* @param string $value * @param string $value
* @param array|string $columns * @param array|string $columns
* *
* @return Model
*
* @throws ObjectNotFoundException * @throws ObjectNotFoundException
*
* @return Model
*/ */
public function findByOrFail($attribute, $value, $columns = ['*']) public function findByOrFail($attribute, $value, $columns = ['*'])
{ {
@ -796,9 +830,9 @@ class Builder
* @param string $dn * @param string $dn
* @param array|string $columns * @param array|string $columns
* *
* @return Model|static
*
* @throws ObjectNotFoundException * @throws ObjectNotFoundException
*
* @return Model|static
*/ */
public function findOrFail($dn, $columns = ['*']) public function findOrFail($dn, $columns = ['*'])
{ {
@ -917,27 +951,24 @@ class Builder
* @param string $boolean * @param string $boolean
* @param bool $raw * @param bool $raw
* *
* @return $this
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*
* @return $this
*/ */
public function where($field, $operator = null, $value = null, $boolean = 'and', $raw = false) public function where($field, $operator = null, $value = null, $boolean = 'and', $raw = false)
{ {
if (is_array($field)) { if (is_array($field)) {
// If the field is an array, we will assume it is an array of // If the field is an array, we will assume we have been
// key-value pairs and can add them each as a where clause. // provided with an array of key-value pairs and can
// add them each as their own seperate where clause.
return $this->addArrayOfWheres($field, $boolean, $raw); return $this->addArrayOfWheres($field, $boolean, $raw);
} }
// We'll bypass the 'has' and 'notHas' operator since they // If we have been provided with two arguments not a "has" or
// only require two arguments inside the where method. // "not has" operator, we'll assume the developer is creating
$bypass = ['*', '!*']; // an "equals" clause and set the proper operator in place.
if (func_num_args() === 2 && ! in_array($operator, ['*', '!*'])) {
// Here we will make some assumptions about the operator. If only [$value, $operator] = [$operator, '='];
// 2 values are passed to the method, we will assume that
// the operator is 'equals' and keep going.
if (func_num_args() === 2 && in_array($operator, $bypass) === false) {
list($value, $operator) = [$operator, '='];
} }
if (! in_array($operator, $this->grammar->getOperators())) { if (! in_array($operator, $this->grammar->getOperators())) {
@ -1378,30 +1409,28 @@ class Builder
} }
/** /**
* Adds a filter onto the current query. * Adds a filter binding onto the current query.
* *
* @param string $type The type of filter to add. * @param string $type The type of filter to add.
* @param array $bindings The bindings of the filter. * @param array $bindings The bindings of the filter.
* *
* @return $this
*
* @throws InvalidArgumentException * @throws InvalidArgumentException
*
* @return $this
*/ */
public function addFilter($type, array $bindings) public function addFilter($type, array $bindings)
{ {
if (! array_key_exists($type, $this->filters)) { if (! array_key_exists($type, $this->filters)) {
throw new InvalidArgumentException("Filter type [$type] is invalid."); throw new InvalidArgumentException("Filter type: [$type] is invalid.");
} }
// The required filter key bindings. // Each filter clause require key bindings to be set. We
$required = ['field', 'operator', 'value']; // will validate this here to ensure all of them have
// been provided, or throw an exception otherwise.
if ($missing = $this->missingBindingKeys($bindings)) {
$keys = implode(', ', $missing);
// Here we will ensure the proper key bindings are given. throw new InvalidArgumentException("Invalid filter bindings. Missing: [$keys] keys.");
if (count(array_intersect_key(array_flip($required), $bindings)) !== count($required)) {
// Retrieve the keys that are missing in the bindings array.
$missing = implode(', ', array_diff($required, array_flip($bindings)));
throw new InvalidArgumentException("Invalid filter bindings. Missing: [$missing] keys.");
} }
$this->filters[$type][] = $bindings; $this->filters[$type][] = $bindings;
@ -1409,6 +1438,22 @@ class Builder
return $this; return $this;
} }
/**
* Extract any missing required binding keys.
*
* @param array $bindings
*
* @return array
*/
protected function missingBindingKeys($bindings)
{
$required = array_flip(['field', 'operator', 'value']);
$existing = array_intersect_key($required, $bindings);
return array_keys(array_diff_key($required, $existing));
}
/** /**
* Get all the filters on the query. * Get all the filters on the query.
* *
@ -1426,7 +1471,7 @@ class Builder
*/ */
public function clearFilters() public function clearFilters()
{ {
foreach ($this->filters as $type => $filters) { foreach (array_keys($this->filters) as $type) {
$this->filters[$type] = []; $this->filters[$type] = [];
} }
@ -1565,9 +1610,9 @@ class Builder
* @param string $dn * @param string $dn
* @param array $attributes * @param array $attributes
* *
* @return bool
*
* @throws LdapRecordException * @throws LdapRecordException
*
* @return bool
*/ */
public function insert($dn, array $attributes) public function insert($dn, array $attributes)
{ {
@ -1683,9 +1728,9 @@ class Builder
* @param string $method * @param string $method
* @param array $parameters * @param array $parameters
* *
* @return mixed
*
* @throws BadMethodCallException * @throws BadMethodCallException
*
* @return mixed
*/ */
public function __call($method, $parameters) public function __call($method, $parameters)
{ {
@ -1760,7 +1805,7 @@ class Builder
if (is_numeric($key) && is_array($value)) { if (is_numeric($key) && is_array($value)) {
// If the key is numeric and the value is an array, we'll // If the key is numeric and the value is an array, we'll
// assume we've been given an array with conditionals. // assume we've been given an array with conditionals.
list($field, $condition) = $value; [$field, $condition] = $value;
// Since a value is optional for some conditionals, we will // Since a value is optional for some conditionals, we will
// try and retrieve the third parameter from the array, // try and retrieve the third parameter from the array,
@ -1818,6 +1863,9 @@ class Builder
case 'read': case 'read':
$event = new Events\Read(...$args); $event = new Events\Read(...$args);
break; break;
case 'chunk':
$event = new Events\Chunk(...$args);
break;
case 'paginate': case 'paginate':
$event = new Events\Paginate(...$args); $event = new Events\Paginate(...$args);
break; break;

View File

@ -0,0 +1,8 @@
<?php
namespace LdapRecord\Query\Events;
class Chunk extends QueryExecuted
{
//
}

View File

@ -142,7 +142,10 @@ class Grammar
{ {
$filter = $this->compileWheres($query, 'or'); $filter = $this->compileWheres($query, 'or');
if ($this->hasMultipleFilters($query)) { if (! $this->hasMultipleFilters($query)) {
return $filter;
}
// Here we will detect whether the entire query can be // Here we will detect whether the entire query can be
// wrapped inside of an "or" statement by checking // wrapped inside of an "or" statement by checking
// how many filter statements exist for each type. // how many filter statements exist for each type.
@ -151,7 +154,6 @@ class Grammar
} else { } else {
$filter = $this->compileOr($filter); $filter = $this->compileOr($filter);
} }
}
return $filter; return $filter;
} }
@ -270,7 +272,9 @@ class Grammar
*/ */
public function compileDoesNotEqual($field, $value) public function compileDoesNotEqual($field, $value)
{ {
return $this->compileNot($this->compileEquals($field, $value)); return $this->compileNot(
$this->compileEquals($field, $value)
);
} }
/** /**
@ -360,7 +364,9 @@ class Grammar
*/ */
public function compileNotStartsWith($field, $value) public function compileNotStartsWith($field, $value)
{ {
return $this->compileNot($this->compileStartsWith($field, $value)); return $this->compileNot(
$this->compileStartsWith($field, $value)
);
} }
/** /**
@ -420,7 +426,9 @@ class Grammar
*/ */
public function compileNotContains($field, $value) public function compileNotContains($field, $value)
{ {
return $this->compileNot($this->compileContains($field, $value)); return $this->compileNot(
$this->compileContains($field, $value)
);
} }
/** /**
@ -448,7 +456,9 @@ class Grammar
*/ */
public function compileNotHas($field) public function compileNotHas($field)
{ {
return $this->compileNot($this->compileHas($field)); return $this->compileNot(
$this->compileHas($field)
);
} }
/** /**
@ -496,18 +506,44 @@ class Grammar
* *
* @param array $where * @param array $where
* *
* @return string
*
* @throws UnexpectedValueException * @throws UnexpectedValueException
*
* @return string
*/ */
protected function compileWhere(array $where) protected function compileWhere(array $where)
{ {
if (! array_key_exists($where['operator'], $this->operators)) { $method = $this->makeCompileMethod($where['operator']);
throw new UnexpectedValueException('Invalid LDAP filter operator ['.$where['operator'].']');
}
$method = 'compile'.ucfirst($this->operators[$where['operator']]);
return $this->{$method}($where['field'], $where['value']); return $this->{$method}($where['field'], $where['value']);
} }
/**
* Make the compile method name for the operator.
*
* @param string $operator
*
* @throws UnexpectedValueException
*
* @return string
*/
protected function makeCompileMethod($operator)
{
if (! $this->operatorExists($operator)) {
throw new UnexpectedValueException("Invalid LDAP filter operator ['$operator']");
}
return 'compile'.ucfirst($this->operators[$operator]);
}
/**
* Determine if the operator exists.
*
* @param string $operator
*
* @return bool
*/
protected function operatorExists($operator)
{
return array_key_exists($operator, $this->operators);
}
} }

View File

@ -34,9 +34,9 @@ class ActiveDirectoryBuilder extends Builder
* @param string $sid * @param string $sid
* @param array|string $columns * @param array|string $columns
* *
* @return \LdapRecord\Models\ActiveDirectory\Entry|static
*
* @throws ModelNotFoundException * @throws ModelNotFoundException
*
* @return \LdapRecord\Models\ActiveDirectory\Entry|static
*/ */
public function findBySidOrFail($sid, $columns = []) public function findBySidOrFail($sid, $columns = [])
{ {

View File

@ -181,9 +181,9 @@ class Builder extends BaseBuilder
* @param string $value * @param string $value
* @param array|string $columns * @param array|string $columns
* *
* @return Model
*
* @throws ModelNotFoundException * @throws ModelNotFoundException
*
* @return Model
*/ */
public function findByAnrOrFail($value, $columns = ['*']) public function findByAnrOrFail($value, $columns = ['*'])
{ {
@ -271,9 +271,9 @@ class Builder extends BaseBuilder
* @param string $guid * @param string $guid
* @param array|string $columns * @param array|string $columns
* *
* @return Model|static
*
* @throws ModelNotFoundException * @throws ModelNotFoundException
*
* @return Model|static
*/ */
public function findByGuidOrFail($guid, $columns = ['*']) public function findByGuidOrFail($guid, $columns = ['*'])
{ {

View File

@ -4,6 +4,9 @@ namespace LdapRecord\Query\Pagination;
use LdapRecord\LdapInterface; use LdapRecord\LdapInterface;
/**
* @deprecated
*/
class DeprecatedPaginator extends AbstractPaginator class DeprecatedPaginator extends AbstractPaginator
{ {
/** /**

View File

@ -0,0 +1,34 @@
<?php
namespace LdapRecord\Query\Pagination;
use LdapRecord\LdapInterface;
class LazyPaginator extends Paginator
{
/**
* Execute the pagination request.
*
* @param LdapInterface $ldap
*
* @return Generator
*/
public function execute(LdapInterface $ldap)
{
$this->prepareServerControls();
do {
$this->applyServerControls($ldap);
if (! $resource = $this->query->run($this->filter)) {
break;
}
$this->updateServerControls($ldap, $resource);
yield $this->query->parse($resource);
} while (! empty($this->fetchCookie()));
$this->resetServerControls($ldap);
}
}

View File

@ -0,0 +1,139 @@
<?php
namespace LdapRecord\Support;
use ArrayAccess;
class Arr
{
/**
* Determine whether the given value is array accessible.
*
* @param mixed $value
*
* @return bool
*/
public static function accessible($value)
{
return is_array($value) || $value instanceof ArrayAccess;
}
/**
* Determine if the given key exists in the provided array.
*
* @param \ArrayAccess|array $array
* @param string|int $key
*
* @return bool
*/
public static function exists($array, $key)
{
if ($array instanceof ArrayAccess) {
return $array->offsetExists($key);
}
return array_key_exists($key, $array);
}
/**
* If the given value is not an array and not null, wrap it in one.
*
* @param mixed $value
*
* @return array
*/
public static function wrap($value)
{
if (is_null($value)) {
return [];
}
return is_array($value) ? $value : [$value];
}
/**
* Return the first element in an array passing a given truth test.
*
* @param iterable $array
* @param callable|null $callback
* @param mixed $default
*
* @return mixed
*/
public static function first($array, callable $callback = null, $default = null)
{
if (is_null($callback)) {
if (empty($array)) {
return Helpers::value($default);
}
foreach ($array as $item) {
return $item;
}
}
foreach ($array as $key => $value) {
if ($callback($value, $key)) {
return $value;
}
}
return Helpers::value($default);
}
/**
* Return the last element in an array passing a given truth test.
*
* @param array $array
* @param callable|null $callback
* @param mixed $default
*
* @return mixed
*/
public static function last($array, callable $callback = null, $default = null)
{
if (is_null($callback)) {
return empty($array) ? Helpers::value($default) : end($array);
}
return static::first(array_reverse($array, true), $callback, $default);
}
/**
* Get an item from an array using "dot" notation.
*
* @param ArrayAccess|array $array
* @param string|int|null $key
* @param mixed $default
*
* @return mixed
*/
public static function get($array, $key, $default = null)
{
if (! static::accessible($array)) {
return Helpers::value($default);
}
if (is_null($key)) {
return $array;
}
if (static::exists($array, $key)) {
return $array[$key];
}
if (strpos($key, '.') === false) {
return $array[$key] ?? Helpers::value($default);
}
foreach (explode('.', $key) as $segment) {
if (static::accessible($array) && static::exists($array, $segment)) {
$array = $array[$segment];
} else {
return Helpers::value($default);
}
}
return $array;
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace LdapRecord\Support;
use Closure;
class Helpers
{
/**
* Return the default value of the given value.
*
* @param mixed $value
*
* @return mixed
*/
public static function value($value)
{
return $value instanceof Closure ? $value() : $value;
}
}

View File

@ -32,7 +32,7 @@ class ConnectionFake extends Connection
*/ */
public static function make(array $config = [], $ldap = LdapFake::class) public static function make(array $config = [], $ldap = LdapFake::class)
{ {
return new static($config, new $ldap); return new static($config, new $ldap());
} }
/** /**

View File

@ -11,9 +11,9 @@ class DirectoryFake
* *
* @param string|null $name * @param string|null $name
* *
* @return ConnectionFake
*
* @throws \LdapRecord\ContainerException * @throws \LdapRecord\ContainerException
*
* @return ConnectionFake
*/ */
public static function setup($name = null) public static function setup($name = null)
{ {

View File

@ -5,6 +5,7 @@ namespace LdapRecord\Testing;
use Exception; use Exception;
use LdapRecord\DetailedError; use LdapRecord\DetailedError;
use LdapRecord\LdapBase; use LdapRecord\LdapBase;
use LdapRecord\Support\Arr;
use PHPUnit\Framework\Assert as PHPUnit; use PHPUnit\Framework\Assert as PHPUnit;
use PHPUnit\Framework\Constraint\Constraint; use PHPUnit\Framework\Constraint\Constraint;
@ -73,7 +74,7 @@ class LdapFake extends LdapBase
*/ */
public function expect($expectations = []) public function expect($expectations = [])
{ {
$expectations = is_array($expectations) ? $expectations : [$expectations]; $expectations = Arr::wrap($expectations);
foreach ($expectations as $key => $expectation) { foreach ($expectations as $key => $expectation) {
// If the key is non-numeric, we will assume // If the key is non-numeric, we will assume
@ -285,7 +286,7 @@ class LdapFake extends LdapBase
{ {
$this->bound = false; $this->bound = false;
$this->host = $this->getConnectionString($hosts, $port); $this->host = $this->makeConnectionUris($hosts, $port);
return $this->connection = $this->hasExpectations('connect') return $this->connection = $this->hasExpectations('connect')
? $this->resolveExpectation('connect', func_get_args()) ? $this->resolveExpectation('connect', func_get_args())
@ -448,9 +449,9 @@ class LdapFake extends LdapBase
* @param string $method * @param string $method
* @param array $args * @param array $args
* *
* @return mixed
*
* @throws Exception * @throws Exception
*
* @return mixed
*/ */
protected function resolveExpectation($method, $args = []) protected function resolveExpectation($method, $args = [])
{ {

View File

@ -0,0 +1,20 @@
<?php
namespace Illuminate\Contracts\Broadcasting;
interface HasBroadcastChannel
{
/**
* Get the broadcast channel route definition that is associated with the given entity.
*
* @return string
*/
public function broadcastChannelRoute();
/**
* Get the broadcast channel name that is associated with the given entity.
*
* @return string
*/
public function broadcastChannel();
}

View File

@ -7,8 +7,8 @@ interface SupportsPartialRelations
/** /**
* Indicate that the relation is a single result of a larger one-to-many relationship. * Indicate that the relation is a single result of a larger one-to-many relationship.
* *
* @param \Closure|string|null $column * @param string|null $column
* @param string|null $relation * @param string|\Closure|null $aggregate
* @param string $relation * @param string $relation
* @return $this * @return $this
*/ */
@ -20,4 +20,11 @@ interface SupportsPartialRelations
* @return bool * @return bool
*/ */
public function isOneOfMany(); public function isOneOfMany();
/**
* Get the one of many inner join subselect query builder instance.
*
* @return \Illuminate\Database\Eloquent\Builder|void
*/
public function getOneOfManySubQuery();
} }

View File

@ -0,0 +1,14 @@
<?php
namespace Illuminate\Contracts\Validation;
interface ValidatorAwareRule
{
/**
* Set the current validator.
*
* @param \Illuminate\Validation\Validator $validator
* @return $this
*/
public function setValidator($validator);
}

View File

@ -117,21 +117,28 @@ This project exists thanks to all the people who contribute.
[Thanks to people helping us to translate Carbon in so many languages](https://carbon.nesbot.com/contribute/translators/) [Thanks to people helping us to translate Carbon in so many languages](https://carbon.nesbot.com/contribute/translators/)
### Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/Carbon#backer)]
<a href="https://opencollective.com/Carbon#backers" target="_blank"><img src="https://opencollective.com/Carbon/backers.svg?width=890"></a>
### Sponsors ### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/Carbon#sponsor)] Support this project by becoming a sponsor. Your logo will show up here with a link to your website.
<a href="https://tidelift.com/subscription/pkg/packagist-nesbot-carbon?utm_source=packagist-nesbot-carbon&utm_medium=referral&utm_campaign=readme" target="_blank"><img src="https://carbon.nesbot.com/tidelift-brand.png" width="256" height="64"></a>
<a href="https://onlinecasinohex.ca/?utm_source=opencollective&amp;utm_medium=github&amp;utm_campaign=Carbon" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/0/avatar.svg" width="192" height="64"></a>
<a href="https://opencollective.com/Carbon/sponsor/0/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/0/avatar.svg"></a> <a href="https://opencollective.com/Carbon/sponsor/0/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/Carbon/sponsor/1/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/1/avatar.svg"></a> <a href="https://opencollective.com/Carbon/sponsor/1/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/Carbon/sponsor/2/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/2/avatar.svg"></a> <a href="https://opencollective.com/Carbon/sponsor/2/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/Carbon/sponsor/3/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/3/avatar.svg"></a> <a href="https://opencollective.com/Carbon/sponsor/3/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/Carbon/sponsor/4/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/4/avatar.svg"></a> <a href="https://opencollective.com/Carbon/sponsor/4/website" target="_blank"><img src="https://opencollective.com/Carbon/sponsor/4/avatar.svg"></a>
[[Become a sponsor](https://opencollective.com/Carbon#sponsor)]
### Backers
Thank you to all our backers! 🙏
<a href="https://opencollective.com/Carbon#backers" target="_blank"><img src="https://opencollective.com/Carbon/backers.svg?width=890"></a>
[[Become a backer](https://opencollective.com/Carbon#backer)]
## Carbon for enterprise ## Carbon for enterprise
Available as part of the Tidelift Subscription. Available as part of the Tidelift Subscription.

View File

@ -1226,6 +1226,25 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
*/ */
public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null); public static function createSafe($year = null, $month = null, $day = null, $hour = null, $minute = null, $second = null, $tz = null);
/**
* Create a new Carbon instance from a specific date and time using strict validation.
*
* @see create()
*
* @param int|null $year
* @param int|null $month
* @param int|null $day
* @param int|null $hour
* @param int|null $minute
* @param int|null $second
* @param DateTimeZone|string|null $tz
*
* @throws InvalidFormatException
*
* @return static
*/
public static function createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $tz = null);
/** /**
* Get/set the day of year. * Get/set the day of year.
* *
@ -2284,7 +2303,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return string * @return string
*/ */
public function getTranslationMessage(string $key, string $locale = null, string $default = null, $translator = null); public function getTranslationMessage(string $key, ?string $locale = null, ?string $default = null, $translator = null);
/** /**
* Returns raw translation message for a given key. * Returns raw translation message for a given key.
@ -2296,7 +2315,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return string * @return string
*/ */
public static function getTranslationMessageWith($translator, string $key, string $locale = null, string $default = null); public static function getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null);
/** /**
* Get the default translator instance in use. * Get the default translator instance in use.
@ -2934,7 +2953,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return string * @return string
*/ */
public function isoFormat(string $format, string $originalFormat = null): string; public function isoFormat(string $format, ?string $originalFormat = null): string;
/** /**
* Get/set the week number using given first day of week and first * Get/set the week number using given first day of week and first
@ -3066,7 +3085,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return $this|string * @return $this|string
*/ */
public function locale(string $locale = null, ...$fallbackLocales); public function locale(?string $locale = null, ...$fallbackLocales);
/** /**
* Returns true if the given locale is internally supported and has words for 1-day diff (just now, yesterday, tomorrow). * Returns true if the given locale is internally supported and has words for 1-day diff (just now, yesterday, tomorrow).
@ -3423,7 +3442,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return string * @return string
*/ */
public function ordinal(string $key, string $period = null): string; public function ordinal(string $key, ?string $period = null): string;
/** /**
* Create a carbon instance from a string. * Create a carbon instance from a string.
@ -4737,7 +4756,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return string * @return string
*/ */
public function translate(string $key, array $parameters = [], $number = null, \Symfony\Component\Translation\TranslatorInterface $translator = null, bool $altNumbers = false): string; public function translate(string $key, array $parameters = [], $number = null, ?\Symfony\Component\Translation\TranslatorInterface $translator = null, bool $altNumbers = false): string;
/** /**
* Returns the alternative number for a given integer if available in the current locale. * Returns the alternative number for a given integer if available in the current locale.
@ -4907,7 +4926,7 @@ interface CarbonInterface extends DateTimeInterface, JsonSerializable
* *
* @return int|static * @return int|static
*/ */
public function utcOffset(int $minuteOffset = null); public function utcOffset(?int $minuteOffset = null);
/** /**
* Returns the milliseconds timestamps used amongst other by Date javascript objects. * Returns the milliseconds timestamps used amongst other by Date javascript objects.

View File

@ -27,6 +27,7 @@ use Closure;
use DateInterval; use DateInterval;
use Exception; use Exception;
use ReflectionException; use ReflectionException;
use ReturnTypeWillChange;
use Throwable; use Throwable;
/** /**
@ -522,6 +523,8 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
$interval = implode($match[1], $interval); $interval = implode($match[1], $interval);
} }
$interval = $interval ?? '';
for ($index = 0; $index < $length; $index++) { for ($index = 0; $index < $length; $index++) {
$expected = mb_substr($format, $index, 1); $expected = mb_substr($format, $index, 1);
$nextCharacter = mb_substr($interval, 0, 1); $nextCharacter = mb_substr($interval, 0, 1);
@ -963,6 +966,7 @@ class CarbonInterval extends DateInterval implements CarbonConverterInterface
* *
* @link http://php.net/manual/en/dateinterval.createfromdatestring.php * @link http://php.net/manual/en/dateinterval.createfromdatestring.php
*/ */
#[ReturnTypeWillChange]
public static function createFromDateString($time) public static function createFromDateString($time)
{ {
$interval = @parent::createFromDateString(strtr($time, [ $interval = @parent::createFromDateString(strtr($time, [

View File

@ -479,7 +479,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
$interval = $part; $interval = $part;
} elseif ($start === null && $parsed = Carbon::make($part)) { } elseif ($start === null && $parsed = Carbon::make($part)) {
$start = $part; $start = $part;
} elseif ($end === null && $parsed = Carbon::make(static::addMissingParts($start, $part))) { } elseif ($end === null && $parsed = Carbon::make(static::addMissingParts($start ?? '', $part))) {
$end = $part; $end = $part;
} else { } else {
throw new InvalidPeriodParameterException("Invalid ISO 8601 specification: $iso."); throw new InvalidPeriodParameterException("Invalid ISO 8601 specification: $iso.");
@ -641,7 +641,7 @@ class CarbonPeriod implements Iterator, Countable, JsonSerializable
if ($this->dateInterval === null && if ($this->dateInterval === null &&
( (
\is_string($argument) && preg_match( \is_string($argument) && preg_match(
'/^(\d(\d(?![\/-])|[^\d\/-]([\/-])?)*|P[T0-9].*|(?:\h*\d+(?:\.\d+)?\h*[a-z]+)+)$/i', '/^(-?\d(\d(?![\/-])|[^\d\/-]([\/-])?)*|P[T0-9].*|(?:\h*\d+(?:\.\d+)?\h*[a-z]+)+)$/i',
$argument $argument
) || ) ||
$argument instanceof DateInterval || $argument instanceof DateInterval ||

View File

@ -13,8 +13,14 @@ use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\ConversionException; use Doctrine\DBAL\Types\ConversionException;
use Exception; use Exception;
/**
* @template T of CarbonInterface
*/
trait CarbonTypeConverter trait CarbonTypeConverter
{ {
/**
* @return class-string<T>
*/
protected function getCarbonClassName(): string protected function getCarbonClassName(): string
{ {
return Carbon::class; return Carbon::class;
@ -42,6 +48,8 @@ trait CarbonTypeConverter
/** /**
* @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return T|null
*/ */
public function convertToPHPValue($value, AbstractPlatform $platform) public function convertToPHPValue($value, AbstractPlatform $platform)
{ {
@ -78,6 +86,8 @@ trait CarbonTypeConverter
/** /**
* @SuppressWarnings(PHPMD.UnusedFormalParameter) * @SuppressWarnings(PHPMD.UnusedFormalParameter)
*
* @return string|null
*/ */
public function convertToDatabaseValue($value, AbstractPlatform $platform) public function convertToDatabaseValue($value, AbstractPlatform $platform)
{ {

View File

@ -11,8 +11,12 @@ use Doctrine\DBAL\Types\VarDateTimeImmutableType;
class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType
{ {
/** @use CarbonTypeConverter<CarbonImmutable> */
use CarbonTypeConverter; use CarbonTypeConverter;
/**
* @return class-string<CarbonImmutable>
*/
protected function getCarbonClassName(): string protected function getCarbonClassName(): string
{ {
return CarbonImmutable::class; return CarbonImmutable::class;

View File

@ -6,9 +6,11 @@
*/ */
namespace Carbon\Doctrine; namespace Carbon\Doctrine;
use Carbon\Carbon;
use Doctrine\DBAL\Types\VarDateTimeType; use Doctrine\DBAL\Types\VarDateTimeType;
class DateTimeType extends VarDateTimeType implements CarbonDoctrineType class DateTimeType extends VarDateTimeType implements CarbonDoctrineType
{ {
/** @use CarbonTypeConverter<Carbon> */
use CarbonTypeConverter; use CarbonTypeConverter;
} }

View File

@ -52,6 +52,7 @@ use ReflectionMethod;
* will be 0. * will be 0.
* If one of the set values is not valid, an InvalidDateException * If one of the set values is not valid, an InvalidDateException
* will be thrown. * will be thrown.
* @method CarbonInterface createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $tz = null) Create a new Carbon instance from a specific date and time using strict validation.
* @method Carbon disableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * @method Carbon disableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
* You should rather use the ->settings() method. * You should rather use the ->settings() method.
* @method Carbon enableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * @method Carbon enableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
@ -76,7 +77,7 @@ use ReflectionMethod;
* @method Closure|Carbon getTestNow() Get the Carbon instance (real or mock) to be returned when a "now" * @method Closure|Carbon getTestNow() Get the Carbon instance (real or mock) to be returned when a "now"
* instance is created. * instance is created.
* @method string getTimeFormatByPrecision($unitPrecision) Return a format from H:i to H:i:s.u according to given unit precision. * @method string getTimeFormatByPrecision($unitPrecision) Return a format from H:i to H:i:s.u according to given unit precision.
* @method string getTranslationMessageWith($translator, string $key, string $locale = null, string $default = null) Returns raw translation message for a given key. * @method string getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null) Returns raw translation message for a given key.
* @method \Symfony\Component\Translation\TranslatorInterface getTranslator() Get the default translator instance in use. * @method \Symfony\Component\Translation\TranslatorInterface getTranslator() Get the default translator instance in use.
* @method int getWeekEndsAt() Get the last day of week * @method int getWeekEndsAt() Get the last day of week
* @method int getWeekStartsAt() Get the first day of week * @method int getWeekStartsAt() Get the first day of week

View File

@ -51,6 +51,7 @@ use Closure;
* will be 0. * will be 0.
* If one of the set values is not valid, an InvalidDateException * If one of the set values is not valid, an InvalidDateException
* will be thrown. * will be thrown.
* @method CarbonInterface createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $tz = null) Create a new Carbon instance from a specific date and time using strict validation.
* @method CarbonImmutable disableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * @method CarbonImmutable disableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
* You should rather use the ->settings() method. * You should rather use the ->settings() method.
* @method CarbonImmutable enableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used. * @method CarbonImmutable enableHumanDiffOption($humanDiffOption) @deprecated To avoid conflict between different third-party libraries, static setters should not be used.
@ -75,7 +76,7 @@ use Closure;
* @method Closure|CarbonImmutable getTestNow() Get the Carbon instance (real or mock) to be returned when a "now" * @method Closure|CarbonImmutable getTestNow() Get the Carbon instance (real or mock) to be returned when a "now"
* instance is created. * instance is created.
* @method string getTimeFormatByPrecision($unitPrecision) Return a format from H:i to H:i:s.u according to given unit precision. * @method string getTimeFormatByPrecision($unitPrecision) Return a format from H:i to H:i:s.u according to given unit precision.
* @method string getTranslationMessageWith($translator, string $key, string $locale = null, string $default = null) Returns raw translation message for a given key. * @method string getTranslationMessageWith($translator, string $key, ?string $locale = null, ?string $default = null) Returns raw translation message for a given key.
* @method \Symfony\Component\Translation\TranslatorInterface getTranslator() Get the default translator instance in use. * @method \Symfony\Component\Translation\TranslatorInterface getTranslator() Get the default translator instance in use.
* @method int getWeekEndsAt() Get the last day of week * @method int getWeekEndsAt() Get the last day of week
* @method int getWeekStartsAt() Get the first day of week * @method int getWeekStartsAt() Get the first day of week

View File

@ -24,6 +24,7 @@ if (class_exists('Symfony\\Component\\Translation\\PluralizationRules')) {
* - Serhan Apaydın * - Serhan Apaydın
* - JD Isaacks * - JD Isaacks
* - AbadonnaAbbys * - AbadonnaAbbys
* - Siomkin Alexander
*/ */
return [ return [
'year' => ':count год|:count гады|:count гадоў', 'year' => ':count год|:count гады|:count гадоў',
@ -35,18 +36,18 @@ return [
'week' => ':count тыдзень|:count тыдні|:count тыдняў', 'week' => ':count тыдзень|:count тыдні|:count тыдняў',
'a_week' => '{1}тыдзень|:count тыдзень|:count тыдні|:count тыдняў', 'a_week' => '{1}тыдзень|:count тыдзень|:count тыдні|:count тыдняў',
'w' => ':count тыдзень|:count тыдні|:count тыдняў', 'w' => ':count тыдзень|:count тыдні|:count тыдняў',
'day' => ':count дзень|:count ні|:count дзён', 'day' => ':count дзень|:count дні|:count дзён',
'a_day' => '{1}дзень|:count дзень|:count ні|:count дзён', 'a_day' => '{1}дзень|:count дзень|:count дні|:count дзён',
'd' => ':count дзень|:count ні|:count дзён', 'd' => ':count дн',
'hour' => ':count гадзіну|:count гадзіны|:count гадзін', 'hour' => ':count гадзіну|:count гадзіны|:count гадзін',
'a_hour' => '{1}гадзіна|:count гадзіна|:count гадзіны|:count гадзін', 'a_hour' => '{1}гадзіна|:count гадзіна|:count гадзіны|:count гадзін',
'h' => ':count гадзіна|:count гадзіны|:count гадзін', 'h' => ':count гадзіна|:count гадзіны|:count гадзін',
'minute' => ':count хвіліна|:count хвіліны|:count хвілін', 'minute' => ':count хвіліна|:count хвіліны|:count хвілін',
'a_minute' => '{1}хвіліна|:count хвіліна|:count хвіліны|:count хвілін', 'a_minute' => '{1}хвіліна|:count хвіліна|:count хвіліны|:count хвілін',
'min' => ':count хвіліна|:count хвіліны|:count хвілін', 'min' => ':count хв',
'second' => ':count секунда|:count секунды|:count секунд', 'second' => ':count секунда|:count секунды|:count секунд',
'a_second' => '{1}некалькі секунд|:count секунда|:count секунды|:count секунд', 'a_second' => '{1}некалькі секунд|:count секунда|:count секунды|:count секунд',
's' => ':count секунда|:count секунды|:count секунд', 's' => ':count сек',
'hour_ago' => ':count гадзіну|:count гадзіны|:count гадзін', 'hour_ago' => ':count гадзіну|:count гадзіны|:count гадзін',
'a_hour_ago' => '{1}гадзіну|:count гадзіну|:count гадзіны|:count гадзін', 'a_hour_ago' => '{1}гадзіну|:count гадзіну|:count гадзіны|:count гадзін',

View File

@ -19,6 +19,7 @@ use Carbon\Exceptions\UnitException;
use Closure; use Closure;
use DateTime; use DateTime;
use DateTimeImmutable; use DateTimeImmutable;
use ReturnTypeWillChange;
/** /**
* Trait Converter. * Trait Converter.
@ -75,6 +76,7 @@ trait Converter
* *
* @return string * @return string
*/ */
#[ReturnTypeWillChange]
public function format($format) public function format($format)
{ {
$function = $this->localFormatFunction ?: static::$formatFunction; $function = $this->localFormatFunction ?: static::$formatFunction;

View File

@ -21,6 +21,7 @@ use Closure;
use DateTimeInterface; use DateTimeInterface;
use DateTimeZone; use DateTimeZone;
use Exception; use Exception;
use ReturnTypeWillChange;
/** /**
* Trait Creator. * Trait Creator.
@ -477,6 +478,37 @@ trait Creator
return $instance; return $instance;
} }
/**
* Create a new Carbon instance from a specific date and time using strict validation.
*
* @see create()
*
* @param int|null $year
* @param int|null $month
* @param int|null $day
* @param int|null $hour
* @param int|null $minute
* @param int|null $second
* @param DateTimeZone|string|null $tz
*
* @throws InvalidFormatException
*
* @return static
*/
public static function createStrict(?int $year = 0, ?int $month = 1, ?int $day = 1, ?int $hour = 0, ?int $minute = 0, ?int $second = 0, $tz = null): self
{
$initialStrictMode = static::isStrictModeEnabled();
static::useStrictMode(true);
try {
$date = static::create($year, $month, $day, $hour, $minute, $second, $tz);
} finally {
static::useStrictMode($initialStrictMode);
}
return $date;
}
/** /**
* Create a Carbon instance from just a date. The time portion is set to now. * Create a Carbon instance from just a date. The time portion is set to now.
* *
@ -657,6 +689,7 @@ trait Creator
* *
* @return static|false * @return static|false
*/ */
#[ReturnTypeWillChange]
public static function createFromFormat($format, $time, $tz = null) public static function createFromFormat($format, $time, $tz = null)
{ {
$function = static::$createFromFormatFunction; $function = static::$createFromFormatFunction;
@ -899,6 +932,7 @@ trait Creator
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
#[ReturnTypeWillChange]
public static function getLastErrors() public static function getLastErrors()
{ {
return static::$lastErrors; return static::$lastErrors;

View File

@ -31,6 +31,7 @@ use DateTimeInterface;
use DateTimeZone; use DateTimeZone;
use InvalidArgumentException; use InvalidArgumentException;
use ReflectionException; use ReflectionException;
use ReturnTypeWillChange;
use Throwable; use Throwable;
/** /**
@ -631,6 +632,7 @@ trait Date
* *
* @link http://php.net/manual/en/datetime.gettimezone.php * @link http://php.net/manual/en/datetime.gettimezone.php
*/ */
#[ReturnTypeWillChange]
public function getTimezone() public function getTimezone()
{ {
return CarbonTimeZone::instance(parent::getTimezone()); return CarbonTimeZone::instance(parent::getTimezone());
@ -737,6 +739,30 @@ trait Date
return $date instanceof self ? $date : static::instance($date); return $date instanceof self ? $date : static::instance($date);
} }
/**
* Return the Carbon instance passed through, a now instance in UTC
* if null given or parse the input if string given (using current timezone
* then switching to UTC).
*
* @param Carbon|DateTimeInterface|string|null $date
*
* @return static
*/
protected function resolveUTC($date = null): self
{
if (!$date) {
return static::now('UTC');
}
if (\is_string($date)) {
return static::parse($date, $this->getTimezone())->utc();
}
static::expectDateTime($date, ['null', 'string']);
return $date instanceof self ? $date : static::instance($date)->utc();
}
/** /**
* Return the Carbon instance passed through, a now instance in the same timezone * Return the Carbon instance passed through, a now instance in the same timezone
* if null given or parse the input if string given. * if null given or parse the input if string given.
@ -1398,6 +1424,7 @@ trait Date
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function setDate($year, $month, $day) public function setDate($year, $month, $day)
{ {
return parent::setDate((int) $year, (int) $month, (int) $day); return parent::setDate((int) $year, (int) $month, (int) $day);
@ -1414,6 +1441,7 @@ trait Date
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function setISODate($year, $week, $day = 1) public function setISODate($year, $week, $day = 1)
{ {
return parent::setISODate((int) $year, (int) $week, (int) $day); return parent::setISODate((int) $year, (int) $week, (int) $day);
@ -1449,6 +1477,7 @@ trait Date
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function setTime($hour, $minute, $second = 0, $microseconds = 0) public function setTime($hour, $minute, $second = 0, $microseconds = 0)
{ {
return parent::setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds); return parent::setTime((int) $hour, (int) $minute, (int) $second, (int) $microseconds);
@ -1463,6 +1492,7 @@ trait Date
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function setTimestamp($unixTimestamp) public function setTimestamp($unixTimestamp)
{ {
[$timestamp, $microseconds] = self::getIntegerAndDecimalParts($unixTimestamp); [$timestamp, $microseconds] = self::getIntegerAndDecimalParts($unixTimestamp);
@ -1521,6 +1551,7 @@ trait Date
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function setTimezone($value) public function setTimezone($value)
{ {
return parent::setTimezone(static::safeCreateDateTimeZone($value)); return parent::setTimezone(static::safeCreateDateTimeZone($value));

View File

@ -19,6 +19,7 @@ use Carbon\Translator;
use Closure; use Closure;
use DateInterval; use DateInterval;
use DateTimeInterface; use DateTimeInterface;
use ReturnTypeWillChange;
/** /**
* Trait Difference. * Trait Difference.
@ -117,6 +118,7 @@ trait Difference
* *
* @return DateInterval * @return DateInterval
*/ */
#[ReturnTypeWillChange]
public function diff($date = null, $absolute = false) public function diff($date = null, $absolute = false)
{ {
return parent::diff($this->resolveCarbon($date), (bool) $absolute); return parent::diff($this->resolveCarbon($date), (bool) $absolute);
@ -638,7 +640,7 @@ trait Difference
*/ */
public function floatDiffInRealDays($date = null, $absolute = true) public function floatDiffInRealDays($date = null, $absolute = true)
{ {
$date = $this->resolveCarbon($date)->utc(); $date = $this->resolveUTC($date);
$utc = $this->copy()->utc(); $utc = $this->copy()->utc();
$hoursDiff = $utc->floatDiffInRealHours($date, $absolute); $hoursDiff = $utc->floatDiffInRealHours($date, $absolute);

View File

@ -11,6 +11,7 @@
namespace Carbon\Traits; namespace Carbon\Traits;
use Carbon\CarbonInterface; use Carbon\CarbonInterface;
use ReturnTypeWillChange;
/** /**
* Trait Modifiers. * Trait Modifiers.
@ -429,6 +430,7 @@ trait Modifiers
* *
* @see https://php.net/manual/en/datetime.modify.php * @see https://php.net/manual/en/datetime.modify.php
*/ */
#[ReturnTypeWillChange]
public function modify($modify) public function modify($modify)
{ {
return parent::modify((string) $modify); return parent::modify((string) $modify);

View File

@ -11,6 +11,7 @@
namespace Carbon\Traits; namespace Carbon\Traits;
use Carbon\Exceptions\InvalidFormatException; use Carbon\Exceptions\InvalidFormatException;
use ReturnTypeWillChange;
/** /**
* Trait Serialization. * Trait Serialization.
@ -91,6 +92,7 @@ trait Serialization
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public static function __set_state($dump) public static function __set_state($dump)
{ {
if (\is_string($dump)) { if (\is_string($dump)) {
@ -125,6 +127,7 @@ trait Serialization
/** /**
* Set locale if specified on unserialize() called. * Set locale if specified on unserialize() called.
*/ */
#[ReturnTypeWillChange]
public function __wakeup() public function __wakeup()
{ {
if (get_parent_class() && method_exists(parent::class, '__wakeup')) { if (get_parent_class() && method_exists(parent::class, '__wakeup')) {

View File

@ -16,6 +16,7 @@ use Carbon\CarbonInterval;
use Carbon\Exceptions\UnitException; use Carbon\Exceptions\UnitException;
use Closure; use Closure;
use DateInterval; use DateInterval;
use ReturnTypeWillChange;
/** /**
* Trait Units. * Trait Units.
@ -193,6 +194,7 @@ trait Units
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function add($unit, $value = 1, $overflow = null) public function add($unit, $value = 1, $overflow = null)
{ {
if (\is_string($unit) && \func_num_args() === 1) { if (\is_string($unit) && \func_num_args() === 1) {
@ -352,6 +354,7 @@ trait Units
* *
* @return static * @return static
*/ */
#[ReturnTypeWillChange]
public function sub($unit, $value = 1, $overflow = null) public function sub($unit, $value = 1, $overflow = null)
{ {
if (\is_string($unit) && \func_num_args() === 1) { if (\is_string($unit) && \func_num_args() === 1) {

View File

@ -2,6 +2,11 @@
Please disclose any security issues or vulnerabilities found through [Tidelift's coordinated disclosure system](https://tidelift.com/security) or to the maintainers privately. Please disclose any security issues or vulnerabilities found through [Tidelift's coordinated disclosure system](https://tidelift.com/security) or to the maintainers privately.
PHPMailer 6.4.1 and earlier contain a vulnerability that can result in untrusted code being called (if such code is injected into the host project's scope by other means). If the `$patternselect` parameter to `validateAddress()` is set to `'php'` (the default, defined by `PHPMailer::$validator`), and the global namespace contains a function called `php`, it will be called in preference to the built-in validator of the same name. Mitigated in PHPMailer 6.5.0 by denying the use of simple strings as validator function names. Recorded as [CVE-2021-3603](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-3603). Reported by [Vikrant Singh Chauhan](mailto:vi@hackberry.xyz) via [huntr.dev](https://www.huntr.dev/).
PHPMailer versions 6.4.1 and earlier contain a possible remote code execution vulnerability through the `$lang_path` parameter of the `setLanguage()` method. If the `$lang_path` parameter is passed unfiltered from user input, it can be set to [a UNC path](https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats#unc-paths), and if an attacker is also able to persuade the server to load a file from that UNC path, a script file under their control may be executed. This vulnerability only applies to systems that resolve UNC paths, typically only Microsoft Windows.
PHPMailer 6.5.0 mitigates this by no longer treating translation files as PHP code, but by parsing their text content directly. This approach avoids the possibility of executing unknown code while retaining backward compatibility. This isn't ideal, so the current translation format is deprecated and will be replaced in the next major release. Recorded as [CVE-2021-34551](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-34551). Reported by [Jilin Diting Information Technology Co., Ltd](https://listensec.com) via Tidelift.
PHPMailer versions between 6.1.8 and 6.4.0 contain a regression of the earlier CVE-2018-19296 object injection vulnerability as a result of [a fix for Windows UNC paths in 6.1.8](https://github.com/PHPMailer/PHPMailer/commit/e2e07a355ee8ff36aba21d0242c5950c56e4c6f9). Recorded as [CVE-2020-36326](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-36326). Reported by Fariskhi Vidyan via Tidelift. 6.4.1 fixes this issue, and also enforces stricter checks for URL schemes in local path contexts. PHPMailer versions between 6.1.8 and 6.4.0 contain a regression of the earlier CVE-2018-19296 object injection vulnerability as a result of [a fix for Windows UNC paths in 6.1.8](https://github.com/PHPMailer/PHPMailer/commit/e2e07a355ee8ff36aba21d0242c5950c56e4c6f9). Recorded as [CVE-2020-36326](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-36326). Reported by Fariskhi Vidyan via Tidelift. 6.4.1 fixes this issue, and also enforces stricter checks for URL schemes in local path contexts.
PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs in `Content-Type` and `Content-Disposition` when filenames passed into `addAttachment` and other methods that accept attachment names contain double quote characters, in contravention of RFC822 3.4.1. No specific vulnerability has been found relating to this, but it could allow file attachments to bypass attachment filters that are based on matching filename extensions. Recorded as [CVE-2020-13625](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-13625). Reported by Elar Lang of Clarified Security. PHPMailer versions 6.1.5 and earlier contain an output escaping bug that occurs in `Content-Type` and `Content-Disposition` when filenames passed into `addAttachment` and other methods that accept attachment names contain double quote characters, in contravention of RFC822 3.4.1. No specific vulnerability has been found relating to this, but it could allow file attachments to bypass attachment filters that are based on matching filename extensions. Recorded as [CVE-2020-13625](https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-13625). Reported by Elar Lang of Clarified Security.

View File

@ -1 +1 @@
6.4.1 6.5.0

View File

@ -19,8 +19,7 @@ $PHPMAILER_LANG['instantiate'] = 'لا يمكن توفير خدمة ا
$PHPMAILER_LANG['invalid_address'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: '; $PHPMAILER_LANG['invalid_address'] = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: ';
$PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.'; $PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.';
$PHPMAILER_LANG['provide_address'] = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.'; $PHPMAILER_LANG['provide_address'] = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.';
$PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية ' . $PHPMAILER_LANG['recipients_failed'] = 'خطأ SMTP: الأخطاء التالية فشل في الارسال لكل من : ';
'فشل في الارسال لكل من : ';
$PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: '; $PHPMAILER_LANG['signing'] = 'خطأ في التوقيع: ';
$PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() غير ممكن.'; $PHPMAILER_LANG['smtp_connect_failed'] = 'SMTP Connect() غير ممكن.';
$PHPMAILER_LANG['smtp_error'] = 'خطأ على مستوى الخادم SMTP: '; $PHPMAILER_LANG['smtp_error'] = 'خطأ على مستوى الخادم SMTP: ';

View File

@ -428,9 +428,11 @@ class PHPMailer
public $Debugoutput = 'echo'; public $Debugoutput = 'echo';
/** /**
* Whether to keep SMTP connection open after each message. * Whether to keep the SMTP connection open after each message.
* If this is set to true then to close the connection * If this is set to true then the connection will remain open after a send,
* requires an explicit call to smtpClose(). * and closing the connection will require an explicit call to smtpClose().
* It's a good idea to use this if you are sending multiple messages as it reduces overhead.
* See the mailing list example for how to use it.
* *
* @var bool * @var bool
*/ */
@ -748,7 +750,7 @@ class PHPMailer
* *
* @var string * @var string
*/ */
const VERSION = '6.4.1'; const VERSION = '6.5.0';
/** /**
* Error severity: message only, continue processing. * Error severity: message only, continue processing.
@ -1335,7 +1337,8 @@ class PHPMailer
if (null === $patternselect) { if (null === $patternselect) {
$patternselect = static::$validator; $patternselect = static::$validator;
} }
if (is_callable($patternselect)) { //Don't allow strings as callables, see SECURITY.md and CVE-2021-3603
if (is_callable($patternselect) && !is_string($patternselect)) {
return call_user_func($patternselect, $address); return call_user_func($patternselect, $address);
} }
//Reject line breaks in addresses; it's valid RFC5322, but not RFC5321 //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321
@ -2182,7 +2185,8 @@ class PHPMailer
* The default language is English. * The default language is English.
* *
* @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr") * @param string $langcode ISO 639-1 2-character language code (e.g. French is "fr")
* @param string $lang_path Path to the language file directory, with trailing separator (slash) * @param string $lang_path Path to the language file directory, with trailing separator (slash).D
* Do not set this from user input!
* *
* @return bool * @return bool
*/ */
@ -2244,14 +2248,32 @@ class PHPMailer
if (!static::fileIsAccessible($lang_file)) { if (!static::fileIsAccessible($lang_file)) {
$foundlang = false; $foundlang = false;
} else { } else {
//Overwrite language-specific strings. //$foundlang = include $lang_file;
//This way we'll never have missing translation keys. $lines = file($lang_file);
$foundlang = include $lang_file; foreach ($lines as $line) {
//Translation file lines look like this:
//$PHPMAILER_LANG['authenticate'] = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';
//These files are parsed as text and not PHP so as to avoid the possibility of code injection
//See https://blog.stevenlevithan.com/archives/match-quoted-string
$matches = [];
if (
preg_match(
'/^\$PHPMAILER_LANG\[\'([a-z\d_]+)\'\]\s*=\s*(["\'])(.+)*?\2;/',
$line,
$matches
) &&
//Ignore unknown translation keys
array_key_exists($matches[1], $PHPMAILER_LANG)
) {
//Overwrite language-specific strings so we'll never have missing translation keys.
$PHPMAILER_LANG[$matches[1]] = (string)$matches[3];
}
}
} }
} }
$this->language = $PHPMAILER_LANG; $this->language = $PHPMAILER_LANG;
return (bool) $foundlang; //Returns false if language not found return $foundlang; //Returns false if language not found
} }
/** /**

View File

@ -46,7 +46,7 @@ class POP3
* *
* @var string * @var string
*/ */
const VERSION = '6.4.1'; const VERSION = '6.5.0';
/** /**
* Default POP3 port number. * Default POP3 port number.

View File

@ -35,7 +35,7 @@ class SMTP
* *
* @var string * @var string
*/ */
const VERSION = '6.4.1'; const VERSION = '6.5.0';
/** /**
* SMTP line break constant. * SMTP line break constant.
@ -186,6 +186,7 @@ class SMTP
'Amazon_SES' => '/[\d]{3} Ok (.*)/', 'Amazon_SES' => '/[\d]{3} Ok (.*)/',
'SendGrid' => '/[\d]{3} Ok: queued as (.*)/', 'SendGrid' => '/[\d]{3} Ok: queued as (.*)/',
'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/', 'CampaignMonitor' => '/[\d]{3} 2.0.0 OK:([a-zA-Z\d]{48})/',
'Haraka' => '/[\d]{3} Message Queued \((.*)\)/',
]; ];
/** /**

View File

@ -0,0 +1,3 @@
vendor/
composer.lock
phpunit.xml

View File

@ -0,0 +1,5 @@
CHANGELOG
=========
The changelog is maintained for all Symfony contracts at the following URL:
https://github.com/symfony/contracts/blob/main/CHANGELOG.md

View File

@ -0,0 +1,19 @@
Copyright (c) 2020-2021 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,26 @@
Symfony Deprecation Contracts
=============================
A generic function and convention to trigger deprecation notices.
This package provides a single global function named `trigger_deprecation()` that triggers silenced deprecation notices.
By using a custom PHP error handler such as the one provided by the Symfony ErrorHandler component,
the triggered deprecations can be caught and logged for later discovery, both on dev and prod environments.
The function requires at least 3 arguments:
- the name of the Composer package that is triggering the deprecation
- the version of the package that introduced the deprecation
- the message of the deprecation
- more arguments can be provided: they will be inserted in the message using `printf()` formatting
Example:
```php
trigger_deprecation('symfony/blockchain', '8.9', 'Using "%s" is deprecated, use "%s" instead.', 'bitcoin', 'fabcoin');
```
This will generate the following message:
`Since symfony/blockchain 8.9: Using "bitcoin" is deprecated, use "fabcoin" instead.`
While not necessarily recommended, the deprecation notices can be completely ignored by declaring an empty
`function trigger_deprecation() {}` in your application.

View File

@ -0,0 +1,35 @@
{
"name": "symfony/deprecation-contracts",
"type": "library",
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=7.1"
},
"autoload": {
"files": [
"function.php"
]
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-main": "2.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
}
}

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
if (!function_exists('trigger_deprecation')) {
/**
* Triggers a silenced deprecation notice.
*
* @param string $package The name of the Composer package that is triggering the deprecation
* @param string $version The version of the package that introduced the deprecation
* @param string $message The message of the deprecation
* @param mixed ...$args Values to insert in the message using printf() formatting
*
* @author Nicolas Grekas <p@tchwork.com>
*/
function trigger_deprecation(string $package, string $version, string $message, ...$args): void
{
@trigger_error(($package || $version ? "Since $package $version: " : '').($args ? vsprintf($message, $args) : $message), \E_USER_DEPRECATED);
}
}

View File

@ -101,7 +101,7 @@ final class Mbstring
$fromEncoding = 'Windows-1252'; $fromEncoding = 'Windows-1252';
} }
if ('UTF-8' !== $fromEncoding) { if ('UTF-8' !== $fromEncoding) {
$s = iconv($fromEncoding, 'UTF-8//IGNORE', $s); $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s);
} }
return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s); return preg_replace_callback('/[\x80-\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
@ -112,7 +112,7 @@ final class Mbstring
$fromEncoding = 'UTF-8'; $fromEncoding = 'UTF-8';
} }
return iconv($fromEncoding, $toEncoding.'//IGNORE', $s); return \iconv($fromEncoding, $toEncoding.'//IGNORE', $s);
} }
public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars) public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
@ -129,7 +129,7 @@ final class Mbstring
public static function mb_decode_mimeheader($s) public static function mb_decode_mimeheader($s)
{ {
return iconv_mime_decode($s, 2, self::$internalEncoding); return \iconv_mime_decode($s, 2, self::$internalEncoding);
} }
public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null) public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
@ -165,10 +165,10 @@ final class Mbstring
if ('UTF-8' === $encoding) { if ('UTF-8' === $encoding) {
$encoding = null; $encoding = null;
if (!preg_match('//u', $s)) { if (!preg_match('//u', $s)) {
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
} }
} else { } else {
$s = iconv($encoding, 'UTF-8//IGNORE', $s); $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
} }
$cnt = floor(\count($convmap) / 4) * 4; $cnt = floor(\count($convmap) / 4) * 4;
@ -194,7 +194,7 @@ final class Mbstring
return $s; return $s;
} }
return iconv('UTF-8', $encoding.'//IGNORE', $s); return \iconv('UTF-8', $encoding.'//IGNORE', $s);
} }
public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false) public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = false)
@ -231,10 +231,10 @@ final class Mbstring
if ('UTF-8' === $encoding) { if ('UTF-8' === $encoding) {
$encoding = null; $encoding = null;
if (!preg_match('//u', $s)) { if (!preg_match('//u', $s)) {
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
} }
} else { } else {
$s = iconv($encoding, 'UTF-8//IGNORE', $s); $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
} }
static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4]; static $ulenMask = ["\xC0" => 2, "\xD0" => 2, "\xE0" => 3, "\xF0" => 4];
@ -264,7 +264,7 @@ final class Mbstring
return $result; return $result;
} }
return iconv('UTF-8', $encoding.'//IGNORE', $result); return \iconv('UTF-8', $encoding.'//IGNORE', $result);
} }
public static function mb_convert_case($s, $mode, $encoding = null) public static function mb_convert_case($s, $mode, $encoding = null)
@ -279,10 +279,10 @@ final class Mbstring
if ('UTF-8' === $encoding) { if ('UTF-8' === $encoding) {
$encoding = null; $encoding = null;
if (!preg_match('//u', $s)) { if (!preg_match('//u', $s)) {
$s = @iconv('UTF-8', 'UTF-8//IGNORE', $s); $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
} }
} else { } else {
$s = iconv($encoding, 'UTF-8//IGNORE', $s); $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
} }
if (\MB_CASE_TITLE == $mode) { if (\MB_CASE_TITLE == $mode) {
@ -342,7 +342,7 @@ final class Mbstring
return $s; return $s;
} }
return iconv('UTF-8', $encoding.'//IGNORE', $s); return \iconv('UTF-8', $encoding.'//IGNORE', $s);
} }
public static function mb_internal_encoding($encoding = null) public static function mb_internal_encoding($encoding = null)
@ -353,7 +353,7 @@ final class Mbstring
$normalizedEncoding = self::getEncoding($encoding); $normalizedEncoding = self::getEncoding($encoding);
if ('UTF-8' === $normalizedEncoding || false !== @iconv($normalizedEncoding, $normalizedEncoding, ' ')) { if ('UTF-8' === $normalizedEncoding || false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
self::$internalEncoding = $normalizedEncoding; self::$internalEncoding = $normalizedEncoding;
return true; return true;
@ -412,7 +412,7 @@ final class Mbstring
$encoding = self::$internalEncoding; $encoding = self::$internalEncoding;
} }
return self::mb_detect_encoding($var, [$encoding]) || false !== @iconv($encoding, $encoding, $var); return self::mb_detect_encoding($var, [$encoding]) || false !== @\iconv($encoding, $encoding, $var);
} }
public static function mb_detect_encoding($str, $encodingList = null, $strict = false) public static function mb_detect_encoding($str, $encodingList = null, $strict = false)
@ -487,7 +487,7 @@ final class Mbstring
return \strlen($s); return \strlen($s);
} }
return @iconv_strlen($s, $encoding); return @\iconv_strlen($s, $encoding);
} }
public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null) public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
@ -508,7 +508,7 @@ final class Mbstring
return 0; return 0;
} }
return iconv_strpos($haystack, $needle, $offset, $encoding); return \iconv_strpos($haystack, $needle, $offset, $encoding);
} }
public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null) public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
@ -532,7 +532,7 @@ final class Mbstring
} }
$pos = '' !== $needle || 80000 > \PHP_VERSION_ID $pos = '' !== $needle || 80000 > \PHP_VERSION_ID
? iconv_strrpos($haystack, $needle, $encoding) ? \iconv_strrpos($haystack, $needle, $encoding)
: self::mb_strlen($haystack, $encoding); : self::mb_strlen($haystack, $encoding);
return false !== $pos ? $offset + $pos : false; return false !== $pos ? $offset + $pos : false;
@ -613,7 +613,7 @@ final class Mbstring
} }
if ($start < 0) { if ($start < 0) {
$start = iconv_strlen($s, $encoding) + $start; $start = \iconv_strlen($s, $encoding) + $start;
if ($start < 0) { if ($start < 0) {
$start = 0; $start = 0;
} }
@ -622,13 +622,13 @@ final class Mbstring
if (null === $length) { if (null === $length) {
$length = 2147483647; $length = 2147483647;
} elseif ($length < 0) { } elseif ($length < 0) {
$length = iconv_strlen($s, $encoding) + $length - $start; $length = \iconv_strlen($s, $encoding) + $length - $start;
if ($length < 0) { if ($length < 0) {
return ''; return '';
} }
} }
return (string) iconv_substr($s, $start, $length, $encoding); return (string) \iconv_substr($s, $start, $length, $encoding);
} }
public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null) public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
@ -653,7 +653,7 @@ final class Mbstring
$pos = strrpos($haystack, $needle); $pos = strrpos($haystack, $needle);
} else { } else {
$needle = self::mb_substr($needle, 0, 1, $encoding); $needle = self::mb_substr($needle, 0, 1, $encoding);
$pos = iconv_strrpos($haystack, $needle, $encoding); $pos = \iconv_strrpos($haystack, $needle, $encoding);
} }
return self::getSubpart($pos, $part, $haystack, $encoding); return self::getSubpart($pos, $part, $haystack, $encoding);
@ -732,12 +732,12 @@ final class Mbstring
$encoding = self::getEncoding($encoding); $encoding = self::getEncoding($encoding);
if ('UTF-8' !== $encoding) { if ('UTF-8' !== $encoding) {
$s = iconv($encoding, 'UTF-8//IGNORE', $s); $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
} }
$s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide); $s = preg_replace('/[\x{1100}-\x{115F}\x{2329}\x{232A}\x{2E80}-\x{303E}\x{3040}-\x{A4CF}\x{AC00}-\x{D7A3}\x{F900}-\x{FAFF}\x{FE10}-\x{FE19}\x{FE30}-\x{FE6F}\x{FF00}-\x{FF60}\x{FFE0}-\x{FFE6}\x{20000}-\x{2FFFD}\x{30000}-\x{3FFFD}]/u', '', $s, -1, $wide);
return ($wide << 1) + iconv_strlen($s, 'UTF-8'); return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
} }
public static function mb_substr_count($haystack, $needle, $encoding = null) public static function mb_substr_count($haystack, $needle, $encoding = null)

View File

@ -81,7 +81,7 @@ return array (
'Ī' => 'ī', 'Ī' => 'ī',
'Ĭ' => 'ĭ', 'Ĭ' => 'ĭ',
'Į' => 'į', 'Į' => 'į',
'İ' => 'i', 'İ' => 'i̇',
'IJ' => 'ij', 'IJ' => 'ij',
'Ĵ' => 'ĵ', 'Ĵ' => 'ĵ',
'Ķ' => 'ķ', 'Ķ' => 'ķ',

View File

@ -746,41 +746,41 @@ return array (
'ύ' => 'Ύ', 'ύ' => 'Ύ',
'ὼ' => 'Ὼ', 'ὼ' => 'Ὼ',
'ώ' => 'Ώ', 'ώ' => 'Ώ',
'ᾀ' => '', 'ᾀ' => 'ἈΙ',
'ᾁ' => '', 'ᾁ' => 'ἉΙ',
'ᾂ' => '', 'ᾂ' => 'ἊΙ',
'ᾃ' => '', 'ᾃ' => 'ἋΙ',
'ᾄ' => '', 'ᾄ' => 'ἌΙ',
'ᾅ' => '', 'ᾅ' => 'ἍΙ',
'ᾆ' => '', 'ᾆ' => 'ἎΙ',
'ᾇ' => '', 'ᾇ' => 'ἏΙ',
'ᾐ' => '', 'ᾐ' => 'ἨΙ',
'ᾑ' => '', 'ᾑ' => 'ἩΙ',
'ᾒ' => '', 'ᾒ' => 'ἪΙ',
'ᾓ' => '', 'ᾓ' => 'ἫΙ',
'ᾔ' => '', 'ᾔ' => 'ἬΙ',
'ᾕ' => '', 'ᾕ' => 'ἭΙ',
'ᾖ' => '', 'ᾖ' => 'ἮΙ',
'ᾗ' => '', 'ᾗ' => 'ἯΙ',
'ᾠ' => '', 'ᾠ' => 'ὨΙ',
'ᾡ' => '', 'ᾡ' => 'ὩΙ',
'ᾢ' => '', 'ᾢ' => 'ὪΙ',
'ᾣ' => '', 'ᾣ' => 'ὫΙ',
'ᾤ' => '', 'ᾤ' => 'ὬΙ',
'ᾥ' => '', 'ᾥ' => 'ὭΙ',
'ᾦ' => '', 'ᾦ' => 'ὮΙ',
'ᾧ' => '', 'ᾧ' => 'ὯΙ',
'ᾰ' => 'Ᾰ', 'ᾰ' => 'Ᾰ',
'ᾱ' => 'Ᾱ', 'ᾱ' => 'Ᾱ',
'ᾳ' => '', 'ᾳ' => 'ΑΙ',
'' => 'Ι', '' => 'Ι',
'ῃ' => '', 'ῃ' => 'ΗΙ',
'ῐ' => 'Ῐ', 'ῐ' => 'Ῐ',
'ῑ' => 'Ῑ', 'ῑ' => 'Ῑ',
'ῠ' => 'Ῠ', 'ῠ' => 'Ῠ',
'ῡ' => 'Ῡ', 'ῡ' => 'Ῡ',
'ῥ' => 'Ῥ', 'ῥ' => 'Ῥ',
'ῳ' => '', 'ῳ' => 'ΩΙ',
'ⅎ' => 'Ⅎ', 'ⅎ' => 'Ⅎ',
'' => '', '' => '',
'ⅱ' => 'Ⅱ', 'ⅱ' => 'Ⅱ',
@ -1411,4 +1411,79 @@ return array (
'𞥁' => '𞤟', '𞥁' => '𞤟',
'𞥂' => '𞤠', '𞥂' => '𞤠',
'𞥃' => '𞤡', '𞥃' => '𞤡',
'ß' => 'SS',
'ff' => 'FF',
'fi' => 'FI',
'fl' => 'FL',
'ffi' => 'FFI',
'ffl' => 'FFL',
'ſt' => 'ST',
'st' => 'ST',
'և' => 'ԵՒ',
'ﬓ' => 'ՄՆ',
'ﬔ' => 'ՄԵ',
'ﬕ' => 'ՄԻ',
'ﬖ' => 'ՎՆ',
'ﬗ' => 'ՄԽ',
'ʼn' => 'ʼN',
'ΐ' => 'Ϊ́',
'ΰ' => 'Ϋ́',
'ǰ' => 'J̌',
'ẖ' => 'H̱',
'ẗ' => 'T̈',
'ẘ' => 'W̊',
'ẙ' => 'Y̊',
'ẚ' => 'Aʾ',
'ὐ' => 'Υ̓',
'ὒ' => 'Υ̓̀',
'ὔ' => 'Υ̓́',
'ὖ' => 'Υ̓͂',
'ᾶ' => 'Α͂',
'ῆ' => 'Η͂',
'ῒ' => 'Ϊ̀',
'ΐ' => 'Ϊ́',
'ῖ' => 'Ι͂',
'ῗ' => 'Ϊ͂',
'ῢ' => 'Ϋ̀',
'ΰ' => 'Ϋ́',
'ῤ' => 'Ρ̓',
'ῦ' => 'Υ͂',
'ῧ' => 'Ϋ͂',
'ῶ' => 'Ω͂',
'ᾈ' => 'ἈΙ',
'ᾉ' => 'ἉΙ',
'ᾊ' => 'ἊΙ',
'ᾋ' => 'ἋΙ',
'ᾌ' => 'ἌΙ',
'ᾍ' => 'ἍΙ',
'ᾎ' => 'ἎΙ',
'ᾏ' => 'ἏΙ',
'ᾘ' => 'ἨΙ',
'ᾙ' => 'ἩΙ',
'ᾚ' => 'ἪΙ',
'ᾛ' => 'ἫΙ',
'ᾜ' => 'ἬΙ',
'ᾝ' => 'ἭΙ',
'ᾞ' => 'ἮΙ',
'ᾟ' => 'ἯΙ',
'ᾨ' => 'ὨΙ',
'ᾩ' => 'ὩΙ',
'ᾪ' => 'ὪΙ',
'ᾫ' => 'ὫΙ',
'ᾬ' => 'ὬΙ',
'ᾭ' => 'ὭΙ',
'ᾮ' => 'ὮΙ',
'ᾯ' => 'ὯΙ',
'ᾼ' => 'ΑΙ',
'ῌ' => 'ΗΙ',
'ῼ' => 'ΩΙ',
'ᾲ' => 'ᾺΙ',
'ᾴ' => 'ΆΙ',
'ῂ' => 'ῊΙ',
'ῄ' => 'ΉΙ',
'ῲ' => 'ῺΙ',
'ῴ' => 'ΏΙ',
'ᾷ' => 'Α͂Ι',
'ῇ' => 'Η͂Ι',
'ῷ' => 'Ω͂Ι',
); );

View File

@ -55,7 +55,7 @@ if (!function_exists('mb_detect_order')) {
function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); } function mb_detect_order($encoding = null) { return p\Mbstring::mb_detect_order($encoding); }
} }
if (!function_exists('mb_parse_str')) { if (!function_exists('mb_parse_str')) {
function mb_parse_str($string, &$result = []) { parse_str($string, $result); } function mb_parse_str($string, &$result = []) { parse_str($string, $result); return (bool) $result; }
} }
if (!function_exists('mb_strlen')) { if (!function_exists('mb_strlen')) {
function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); } function mb_strlen($string, $encoding = null) { return p\Mbstring::mb_strlen($string, $encoding); }

View File

@ -48,10 +48,10 @@ if (!function_exists('mb_detect_encoding')) {
function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); } function mb_detect_encoding(?string $string, array|string|null $encodings = null, ?bool $strict = false): string|false { return p\Mbstring::mb_detect_encoding((string) $string, $encodings, (bool) $strict); }
} }
if (!function_exists('mb_detect_order')) { if (!function_exists('mb_detect_order')) {
function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order((string) $encoding); } function mb_detect_order(array|string|null $encoding = null): array|bool { return p\Mbstring::mb_detect_order($encoding); }
} }
if (!function_exists('mb_parse_str')) { if (!function_exists('mb_parse_str')) {
function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); } function mb_parse_str(?string $string, &$result = []): bool { parse_str((string) $string, $result); return (bool) $result; }
} }
if (!function_exists('mb_strlen')) { if (!function_exists('mb_strlen')) {
function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); } function mb_strlen(?string $string, ?string $encoding = null): int { return p\Mbstring::mb_strlen((string) $string, $encoding); }
@ -78,7 +78,7 @@ if (!function_exists('mb_stristr')) {
function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } function mb_stristr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_stristr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
} }
if (!function_exists('mb_strrchr')) { if (!function_exists('mb_strrchr')) {
function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, $before_needle, (bool) $encoding); } function mb_strrchr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrchr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
} }
if (!function_exists('mb_strrichr')) { if (!function_exists('mb_strrichr')) {
function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } function mb_strrichr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strrichr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }

View File

@ -28,7 +28,7 @@
"minimum-stability": "dev", "minimum-stability": "dev",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.22-dev" "dev-main": "1.23-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",

View File

@ -30,7 +30,7 @@
"minimum-stability": "dev", "minimum-stability": "dev",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-main": "1.22-dev" "dev-main": "1.23-dev"
}, },
"thanks": { "thanks": {
"name": "symfony/polyfill", "name": "symfony/polyfill",

View File

@ -1,6 +1,13 @@
CHANGELOG CHANGELOG
========= =========
5.3
---
* Add `translation:pull` and `translation:push` commands to manage translations with third-party providers
* Add `TranslatorBagInterface::getCatalogues` method
* Add support to load XLIFF string in `XliffFileLoader`
5.2.0 5.2.0
----- -----

View File

@ -26,6 +26,10 @@ use Symfony\Component\Translation\MessageCatalogueInterface;
*/ */
abstract class AbstractOperation implements OperationInterface abstract class AbstractOperation implements OperationInterface
{ {
public const OBSOLETE_BATCH = 'obsolete';
public const NEW_BATCH = 'new';
public const ALL_BATCH = 'all';
protected $source; protected $source;
protected $target; protected $target;
protected $result; protected $result;
@ -94,11 +98,11 @@ abstract class AbstractOperation implements OperationInterface
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
} }
if (!isset($this->messages[$domain]['all'])) { if (!isset($this->messages[$domain][self::ALL_BATCH])) {
$this->processDomain($domain); $this->processDomain($domain);
} }
return $this->messages[$domain]['all']; return $this->messages[$domain][self::ALL_BATCH];
} }
/** /**
@ -110,11 +114,11 @@ abstract class AbstractOperation implements OperationInterface
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
} }
if (!isset($this->messages[$domain]['new'])) { if (!isset($this->messages[$domain][self::NEW_BATCH])) {
$this->processDomain($domain); $this->processDomain($domain);
} }
return $this->messages[$domain]['new']; return $this->messages[$domain][self::NEW_BATCH];
} }
/** /**
@ -126,11 +130,11 @@ abstract class AbstractOperation implements OperationInterface
throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain)); throw new InvalidArgumentException(sprintf('Invalid domain: "%s".', $domain));
} }
if (!isset($this->messages[$domain]['obsolete'])) { if (!isset($this->messages[$domain][self::OBSOLETE_BATCH])) {
$this->processDomain($domain); $this->processDomain($domain);
} }
return $this->messages[$domain]['obsolete']; return $this->messages[$domain][self::OBSOLETE_BATCH];
} }
/** /**
@ -147,6 +151,37 @@ abstract class AbstractOperation implements OperationInterface
return $this->result; return $this->result;
} }
/**
* @param self::*_BATCH $batch
*/
public function moveMessagesToIntlDomainsIfPossible(string $batch = self::ALL_BATCH): void
{
// If MessageFormatter class does not exists, intl domains are not supported.
if (!class_exists(\MessageFormatter::class)) {
return;
}
foreach ($this->getDomains() as $domain) {
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
switch ($batch) {
case self::OBSOLETE_BATCH: $messages = $this->getObsoleteMessages($domain); break;
case self::NEW_BATCH: $messages = $this->getNewMessages($domain); break;
case self::ALL_BATCH: $messages = $this->getMessages($domain); break;
default: throw new \InvalidArgumentException(sprintf('$batch argument must be one of ["%s", "%s", "%s"].', self::ALL_BATCH, self::NEW_BATCH, self::OBSOLETE_BATCH));
}
if (!$messages || (!$this->source->all($intlDomain) && $this->source->all($domain))) {
continue;
}
$result = $this->getResult();
$allIntlMessages = $result->all($intlDomain);
$currentMessages = array_diff_key($messages, $result->all($domain));
$result->replace($currentMessages, $domain);
$result->replace($allIntlMessages + $messages, $intlDomain);
}
}
/** /**
* Performs operation on source and target catalogues for the given domain and * Performs operation on source and target catalogues for the given domain and
* stores the results. * stores the results.

View File

@ -0,0 +1,157 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Translation\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Translation\Catalogue\TargetOperation;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\Provider\TranslationProviderCollection;
use Symfony\Component\Translation\Reader\TranslationReaderInterface;
use Symfony\Component\Translation\Writer\TranslationWriterInterface;
/**
* @author Mathieu Santostefano <msantostefano@protonmail.com>
*
* @experimental in 5.3
*/
final class TranslationPullCommand extends Command
{
use TranslationTrait;
protected static $defaultName = 'translation:pull';
protected static $defaultDescription = 'Pull translations from a given provider.';
private $providerCollection;
private $writer;
private $reader;
private $defaultLocale;
private $transPaths;
private $enabledLocales;
public function __construct(TranslationProviderCollection $providerCollection, TranslationWriterInterface $writer, TranslationReaderInterface $reader, string $defaultLocale, array $transPaths = [], array $enabledLocales = [])
{
$this->providerCollection = $providerCollection;
$this->writer = $writer;
$this->reader = $reader;
$this->defaultLocale = $defaultLocale;
$this->transPaths = $transPaths;
$this->enabledLocales = $enabledLocales;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$keys = $this->providerCollection->keys();
$defaultProvider = 1 === \count($keys) ? $keys[0] : null;
$this
->setDefinition([
new InputArgument('provider', null !== $defaultProvider ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The provider to pull translations from.', $defaultProvider),
new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with provider ones (it will delete not synchronized messages).'),
new InputOption('intl-icu', null, InputOption::VALUE_NONE, 'Associated to --force option, it will write messages in "%domain%+intl-icu.%locale%.xlf" files.'),
new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to pull.'),
new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to pull.'),
new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format.', 'xlf12'),
])
->setHelp(<<<'EOF'
The <info>%command.name%</> command pulls translations from the given provider. Only
new translations are pulled, existing ones are not overwritten.
You can overwrite existing translations (and remove the missing ones on local side) by using the <comment>--force</> flag:
<info>php %command.full_name% --force provider</>
Full example:
<info>php %command.full_name% provider --force --domains=messages,validators --locales=en</>
This command pulls all translations associated with the <comment>messages</> and <comment>validators</> domains for the <comment>en</> locale.
Local translations for the specified domains and locale are deleted if they're not present on the provider and overwritten if it's the case.
Local translations for others domains and locales are ignored.
EOF
)
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$provider = $this->providerCollection->get($input->getArgument('provider'));
$force = $input->getOption('force');
$intlIcu = $input->getOption('intl-icu');
$locales = $input->getOption('locales') ?: $this->enabledLocales;
$domains = $input->getOption('domains');
$format = $input->getOption('format');
$xliffVersion = '1.2';
if ($intlIcu && !$force) {
$io->note('--intl-icu option only has an effect when used with --force. Here, it will be ignored.');
}
switch ($format) {
case 'xlf20': $xliffVersion = '2.0';
// no break
case 'xlf12': $format = 'xlf';
}
$writeOptions = [
'path' => end($this->transPaths),
'xliff_version' => $xliffVersion,
];
if (!$domains) {
$domains = $provider->getDomains();
}
$providerTranslations = $provider->read($domains, $locales);
if ($force) {
foreach ($providerTranslations->getCatalogues() as $catalogue) {
$operation = new TargetOperation((new MessageCatalogue($catalogue->getLocale())), $catalogue);
if ($intlIcu) {
$operation->moveMessagesToIntlDomainsIfPossible();
}
$this->writer->write($operation->getResult(), $format, $writeOptions);
}
$io->success(sprintf('Local translations has been updated from "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
$localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
// Append pulled translations to local ones.
$localTranslations->addBag($providerTranslations->diff($localTranslations));
foreach ($localTranslations->getCatalogues() as $catalogue) {
$this->writer->write($catalogue, $format, $writeOptions);
}
$io->success(sprintf('New translations from "%s" has been written locally (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
}

View File

@ -0,0 +1,158 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Translation\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\Translation\Provider\TranslationProviderCollection;
use Symfony\Component\Translation\Reader\TranslationReaderInterface;
use Symfony\Component\Translation\TranslatorBag;
/**
* @author Mathieu Santostefano <msantostefano@protonmail.com>
*
* @experimental in 5.3
*/
final class TranslationPushCommand extends Command
{
use TranslationTrait;
protected static $defaultName = 'translation:push';
protected static $defaultDescription = 'Push translations to a given provider.';
private $providers;
private $reader;
private $transPaths;
private $enabledLocales;
public function __construct(TranslationProviderCollection $providers, TranslationReaderInterface $reader, array $transPaths = [], array $enabledLocales = [])
{
$this->providers = $providers;
$this->reader = $reader;
$this->transPaths = $transPaths;
$this->enabledLocales = $enabledLocales;
parent::__construct();
}
/**
* {@inheritdoc}
*/
protected function configure()
{
$keys = $this->providers->keys();
$defaultProvider = 1 === \count($keys) ? $keys[0] : null;
$this
->setDefinition([
new InputArgument('provider', null !== $defaultProvider ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The provider to push translations to.', $defaultProvider),
new InputOption('force', null, InputOption::VALUE_NONE, 'Override existing translations with local ones (it will delete not synchronized messages).'),
new InputOption('delete-missing', null, InputOption::VALUE_NONE, 'Delete translations available on provider but not locally.'),
new InputOption('domains', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the domains to push.'),
new InputOption('locales', null, InputOption::VALUE_OPTIONAL | InputOption::VALUE_IS_ARRAY, 'Specify the locales to push.', $this->enabledLocales),
])
->setHelp(<<<'EOF'
The <info>%command.name%</> command pushes translations to the given provider. Only new
translations are pushed, existing ones are not overwritten.
You can overwrite existing translations by using the <comment>--force</> flag:
<info>php %command.full_name% --force provider</>
You can delete provider translations which are not present locally by using the <comment>--delete-missing</> flag:
<info>php %command.full_name% --delete-missing provider</>
Full example:
<info>php %command.full_name% provider --force --delete-missing --domains=messages,validators --locales=en</>
This command pushes all translations associated with the <comment>messages</> and <comment>validators</> domains for the <comment>en</> locale.
Provider translations for the specified domains and locale are deleted if they're not present locally and overwritten if it's the case.
Provider translations for others domains and locales are ignored.
EOF
)
;
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output): int
{
if (!$this->enabledLocales) {
throw new InvalidArgumentException('You must define "framework.translator.enabled_locales" or "framework.translator.providers.%s.locales" config key in order to work with translation providers.');
}
$io = new SymfonyStyle($input, $output);
$provider = $this->providers->get($input->getArgument('provider'));
$domains = $input->getOption('domains');
$locales = $input->getOption('locales');
$force = $input->getOption('force');
$deleteMissing = $input->getOption('delete-missing');
$localTranslations = $this->readLocalTranslations($locales, $domains, $this->transPaths);
if (!$domains) {
$domains = $this->getDomainsFromTranslatorBag($localTranslations);
}
if (!$deleteMissing && $force) {
$provider->write($localTranslations);
$io->success(sprintf('All local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
$providerTranslations = $provider->read($domains, $locales);
if ($deleteMissing) {
$provider->delete($providerTranslations->diff($localTranslations));
$io->success(sprintf('Missing translations on "%s" has been deleted (for "%s" locale(s), and "%s" domain(s)).', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
// Read provider translations again, after missing translations deletion,
// to avoid push freshly deleted translations.
$providerTranslations = $provider->read($domains, $locales);
}
$translationsToWrite = $localTranslations->diff($providerTranslations);
if ($force) {
$translationsToWrite->addBag($localTranslations->intersect($providerTranslations));
}
$provider->write($translationsToWrite);
$io->success(sprintf('%s local translations has been sent to "%s" (for "%s" locale(s), and "%s" domain(s)).', $force ? 'All' : 'New', parse_url($provider, \PHP_URL_SCHEME), implode(', ', $locales), implode(', ', $domains)));
return 0;
}
private function getDomainsFromTranslatorBag(TranslatorBag $translatorBag): array
{
$domains = [];
foreach ($translatorBag->getCatalogues() as $catalogue) {
$domains += $catalogue->getDomains();
}
return array_unique($domains);
}
}

View File

@ -0,0 +1,78 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Translation\Command;
use Symfony\Component\Translation\MessageCatalogue;
use Symfony\Component\Translation\MessageCatalogueInterface;
use Symfony\Component\Translation\TranslatorBag;
/**
* @internal
*/
trait TranslationTrait
{
private function readLocalTranslations(array $locales, array $domains, array $transPaths): TranslatorBag
{
$bag = new TranslatorBag();
foreach ($locales as $locale) {
$catalogue = new MessageCatalogue($locale);
foreach ($transPaths as $path) {
$this->reader->read($path, $catalogue);
}
if ($domains) {
foreach ($domains as $domain) {
$catalogue = $this->filterCatalogue($catalogue, $domain);
$bag->addCatalogue($catalogue);
}
} else {
$bag->addCatalogue($catalogue);
}
}
return $bag;
}
private function filterCatalogue(MessageCatalogue $catalogue, string $domain): MessageCatalogue
{
$filteredCatalogue = new MessageCatalogue($catalogue->getLocale());
// extract intl-icu messages only
$intlDomain = $domain.MessageCatalogueInterface::INTL_DOMAIN_SUFFIX;
if ($intlMessages = $catalogue->all($intlDomain)) {
$filteredCatalogue->add($intlMessages, $intlDomain);
}
// extract all messages and subtract intl-icu messages
if ($messages = array_diff($catalogue->all($domain), $intlMessages)) {
$filteredCatalogue->add($messages, $domain);
}
foreach ($catalogue->getResources() as $resource) {
$filteredCatalogue->addResource($resource);
}
if ($metadata = $catalogue->getMetadata('', $intlDomain)) {
foreach ($metadata as $k => $v) {
$filteredCatalogue->setMetadata($k, $v, $intlDomain);
}
}
if ($metadata = $catalogue->getMetadata('', $domain)) {
foreach ($metadata as $k => $v) {
$filteredCatalogue->setMetadata($k, $v, $domain);
}
}
return $filteredCatalogue;
}
}

View File

@ -31,6 +31,7 @@ use Symfony\Component\Translation\Util\XliffUtils;
class XliffLintCommand extends Command class XliffLintCommand extends Command
{ {
protected static $defaultName = 'lint:xliff'; protected static $defaultName = 'lint:xliff';
protected static $defaultDescription = 'Lint an XLIFF file and outputs encountered errors';
private $format; private $format;
private $displayCorrectFiles; private $displayCorrectFiles;
@ -53,7 +54,7 @@ class XliffLintCommand extends Command
protected function configure() protected function configure()
{ {
$this $this
->setDescription('Lint an XLIFF file and outputs encountered errors') ->setDescription(self::$defaultDescription)
->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN') ->addArgument('filename', InputArgument::IS_ARRAY, 'A file, a directory or "-" for reading from STDIN')
->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt') ->addOption('format', null, InputOption::VALUE_REQUIRED, 'The output format', 'txt')
->setHelp(<<<EOF ->setHelp(<<<EOF

View File

@ -79,6 +79,14 @@ class DataCollectorTranslator implements TranslatorInterface, TranslatorBagInter
return $this->translator->getCatalogue($locale); return $this->translator->getCatalogue($locale);
} }
/**
* {@inheritdoc}
*/
public function getCatalogues(): array
{
return $this->translator->getCatalogues();
}
/** /**
* {@inheritdoc} * {@inheritdoc}
* *

View File

@ -25,6 +25,10 @@ class TranslationDumperPass implements CompilerPassInterface
public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper') public function __construct(string $writerServiceId = 'translation.writer', string $dumperTag = 'translation.dumper')
{ {
if (1 < \func_num_args()) {
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
}
$this->writerServiceId = $writerServiceId; $this->writerServiceId = $writerServiceId;
$this->dumperTag = $dumperTag; $this->dumperTag = $dumperTag;
} }

View File

@ -26,6 +26,10 @@ class TranslationExtractorPass implements CompilerPassInterface
public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor') public function __construct(string $extractorServiceId = 'translation.extractor', string $extractorTag = 'translation.extractor')
{ {
if (0 < \func_num_args()) {
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
}
$this->extractorServiceId = $extractorServiceId; $this->extractorServiceId = $extractorServiceId;
$this->extractorTag = $extractorTag; $this->extractorTag = $extractorTag;
} }

View File

@ -26,6 +26,10 @@ class TranslatorPass implements CompilerPassInterface
public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update') public function __construct(string $translatorServiceId = 'translator.default', string $readerServiceId = 'translation.reader', string $loaderTag = 'translation.loader', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update')
{ {
if (0 < \func_num_args()) {
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
}
$this->translatorServiceId = $translatorServiceId; $this->translatorServiceId = $translatorServiceId;
$this->readerServiceId = $readerServiceId; $this->readerServiceId = $readerServiceId;
$this->loaderTag = $loaderTag; $this->loaderTag = $loaderTag;

View File

@ -33,6 +33,10 @@ class TranslatorPathsPass extends AbstractRecursivePass
public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update', string $resolverServiceId = 'argument_resolver.service') public function __construct(string $translatorServiceId = 'translator', string $debugCommandServiceId = 'console.command.translation_debug', string $updateCommandServiceId = 'console.command.translation_update', string $resolverServiceId = 'argument_resolver.service')
{ {
if (0 < \func_num_args()) {
trigger_deprecation('symfony/translation', '5.3', 'Configuring "%s" is deprecated.', __CLASS__);
}
$this->translatorServiceId = $translatorServiceId; $this->translatorServiceId = $translatorServiceId;
$this->debugCommandServiceId = $debugCommandServiceId; $this->debugCommandServiceId = $debugCommandServiceId;
$this->updateCommandServiceId = $updateCommandServiceId; $this->updateCommandServiceId = $updateCommandServiceId;

Some files were not shown because too many files have changed in this diff Show More